Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Datenbanken zusammenfuehren in sqlite3

5 views
Skip to first unread message

Dirk Thierbach

unread,
Apr 27, 2012, 3:00:51 AM4/27/12
to
Ich habe hier ein Programm, dass sqlite3-Datenbanken nutzt. Mehrere
Datenbanken (in verschiedenen Files) dieses Programmes mit jeweils
identischem Tabellenaufbau sollen in eine einzige Datei
zusammengefuehrt werden (mit einem externen zu schreibendem Programm,
Sprache egal). Die Tabellen sehen im Prinzip alle so aus:

CREATE TABLE beispiel (
id INTEGER NOT NULL,
# andere Felder
PRIMARY KEY (id)
);

wobei ggf. "id" in anderen Tabellen referenziert wird.

Wie stelle ich es am geschicktesten an, die "id"-Schluessel und ihre
Referenzen so umzubennen, dass es beim Zusammenfuehren keine
Kollisionen gibt? Notfalls kann man natuerlich "zu Fuss" ueber jeden
Eintrag iterieren und die Umbennenung im ausfuehrenden Programm
vornehmen, aber vielleicht geht es ja auch mit weniger Arbeit und
ein paar SQL-Befehlen.

Danke fuer jeden Hinweis.

- Dirk

Lutz Donnerhacke

unread,
Apr 27, 2012, 4:30:38 AM4/27/12
to
* Dirk Thierbach wrote:
> Wie stelle ich es am geschicktesten an, die "id"-Schluessel und ihre
> Referenzen so umzubennen, dass es beim Zusammenfuehren keine
> Kollisionen gibt?

1) Ändere den FOREIGN KEY auf ON UPDATE CASCADE.
2) Akutalisiere die id Spalte in jeder Instanz auf einen lokal eindeutigen
Bereich ala UPDATE ... SET id = 1000000 + id; wobei der Offset pro
Instanz verschieden sein sollte.
3) Merge
4) Aktualisiere die Sequenz im Merge.


Dirk Thierbach

unread,
Apr 27, 2012, 7:24:09 AM4/27/12
to
Lutz Donnerhacke <lu...@iks-jena.de> wrote:
> * Dirk Thierbach wrote:
>> Wie stelle ich es am geschicktesten an, die "id"-Schluessel und ihre
>> Referenzen so umzubennen, dass es beim Zusammenfuehren keine
>> Kollisionen gibt?

> 1) Ändere den FOREIGN KEY auf ON UPDATE CASCADE.
Den kannte ich noch nicht, guter Trick.

> 2) Akutalisiere die id Spalte in jeder Instanz auf einen lokal eindeutigen
> Bereich ala UPDATE ... SET id = 1000000 + id; wobei der Offset pro
> Instanz verschieden sein sollte.
Das Problem ist, dass der existierende id relativ wuest zu sein scheint,
zumindest kann ich kein System erkennen (alles sehr grosse Zahlen, teilweise
negativ).
Vielleicht kann man ja mit last_insert_rowid() irgendwas basteln,
was die vernuenftig umbenennt. Allerdings bin ich mir nicht sicher, wie
ich dabei evtl. Konflikte am besten behandeln soll.

> 3) Merge
"MERGE INTO" gibt's in sqlite3 nicht, aber das kann man ja simulieren.

> 4) Aktualisiere die Sequenz im Merge.
Verstehe ich nicht. Welche Sequenz? Die der id-Schluessel? Wenn die
nicht aufeinanderfolgen, ist's mir auch egal. :-)

Danke, das hilft schonmal etwas weiter.

- Dirk

Lutz Donnerhacke

unread,
Apr 27, 2012, 8:41:14 AM4/27/12
to
* Dirk Thierbach wrote:
>> 2) Akutalisiere die id Spalte in jeder Instanz auf einen lokal eindeutigen
>> Bereich ala UPDATE ... SET id = 1000000 + id; wobei der Offset pro
>> Instanz verschieden sein sollte.
> Das Problem ist, dass der existierende id relativ wuest zu sein scheint,

Sehr schlecht. Dann steckt da die Hauptarbeit drin.

> Vielleicht kann man ja mit last_insert_rowid() irgendwas basteln,

Eher mit SELECT min(id), max(id) FROM .. auf den verschiednen Systemen.
Die min/max Intervalle dürfen nachher nicht mehr überlappen.
Dazu kannst Du die Bereiche mit einem Offset am Stück verschieben.

>> 3) Merge
> "MERGE INTO" gibt's in sqlite3 nicht, aber das kann man ja simulieren.

Export -> Manuelles Merge -> Import
0 new messages