Ich habe ein grundlegendes Datenbankschema mit zwei Tabellen; Einer ist eine einfache ID - & gt; Textliste der Begriffe, und der andere hat 2 Spalten, Eltern und Kind. Die IDs in der ersten Tabelle werden beim Einfügen durch eine db-Sequenz generiert, während die zweite Tabelle eine Zuordnung zwischen Schlüsseln zum Speichern der "Struktur" der Hierarchie enthält.
Mein Problem ist, dass ich manchmal einen Baum von einer Datenbank in eine andere verschieben möchte. Wenn ich 2 DBs mit jeweils 10 Begriffen habe (Begriffe von Datenbank A! = Begriffe von Datenbank B, und es gibt keine Überschneidungen), und ich kopiere einfach die Daten von A nach B, dann bekomme ich ein offensichtliches Problem, dass die Bedingungen sein werden umnummeriert, aber die Beziehungen werden nicht. In diesem Beispiel funktioniert das Hinzufügen von 10 zu allen Beziehungstasten ganz klar, aber kennt jemand einen allgemeinen Algorithmus dafür?
Die Datenbank ist Oracle 11g, und eine Oracle-spezifische Lösung ist in Ordnung ...
Übersicht
Ich werde vier Lösungen geben, beginnend mit dem einfachsten. Mit jeder Lösung erkläre ich die Situationen, in denen es anwendbar wäre.
Jede dieser Lösungen setzt voraus, dass die Datenbanken A und B die folgenden Tabellen haben:
%Vor%Lösung 1
Dies ist die einfachste Lösung. Es sollte verwendet werden, wenn:
Im Folgenden werden alle Begriffe und Beziehungen von A in B zusammengeführt:
%Vor%Grundsätzlich kopieren Sie zuerst die Begriffe und kopieren dann die Beziehungen, die die alte ID basierend auf dem Text auf die neue ID abbilden.
Hinweis: In Ihrer Frage geben Sie an, dass die Begriffe zwischen den beiden Eingabedatenbanken nicht übereinstimmen. In diesem Fall kann die where
-Klausel in der ersten insert into
weggelassen werden.
Lösung 2
Dies ist die nächst-einfachste Lösung. Es sollte verwendet werden, wenn:
Fügen Sie zuerst eine int-Spalte zu Ihrer Terms-Tabelle mit dem Namen "OldID" hinzu, und verwenden Sie dann Folgendes, um alle Begriffe und Beziehungen von A nach B zusammenzuführen:
%Vor%Lösung 3
Diese Lösung verwendet Iteration. Es sollte verwendet werden, wenn:
Im Folgenden werden alle Begriffe und Beziehungen von A in B zusammengeführt:
%Vor%Lösung 4
Diese Lösung ist Oracle-spezifisch, erfordert, dass Sie die Sequenz kennen, die zum Generieren von ID-Werten verwendet wird, und ist weniger effizient als einige der anderen Lösungen. Es sollte verwendet werden, wenn:
Im Folgenden werden alle Begriffe und Beziehungen von A in B zusammengeführt:
%Vor%Schnelle Antwort
Importieren Sie in eine Zwischenspeichertabelle, füllen Sie jedoch zugeordnete ID-Werte aus derselben Sequenz aus, die zum Erstellen von ID-Werten aus der Zieltabelle verwendet werden. Dies verhindert Konflikte zwischen ID-Werten, da die DBMS-Engine den gleichzeitigen Zugriff auf Sequenzen unterstützt.
Mit den ID-Werten auf dem Knoten, der zugeordnet ist (siehe unten), ist die Neuzuordnung der ID-Werte für die Kanten trivial.
Längere Antwort
Sie benötigen einen Mechanismus, der die Werte zwischen den alten Schlüsseln von der Quelle und neuen Schlüsseln im Ziel abbildet. Die Methode besteht darin, Zwischenspeichertabellen zu erstellen, die die Zuordnungen zwischen dem alten und dem neuen Kays enthalten.
In Oracle werden Autoinkrementierungsschlüssel normalerweise mit Sequenzen in der von Ihnen beschriebenen Weise erstellt. Sie müssen Staging-Tabellen mit einem Platzhalter für den "alten" Schlüssel erstellen, damit Sie die Neuzuordnung vornehmen können. Verwenden Sie die gleiche Sequenz, die von der Anwendung verwendet wird, um die ID-Werte in den tatsächlichen Zieldatenbanktabellen aufzufüllen. Das DBMS ermöglicht gleichzeitige Zugriffe auf Sequenzen und die Verwendung der gleichen Sequenz garantiert, dass Sie keine Kollisionen in den zugeordneten ID-Werten erhalten.
Wenn Sie ein Schema wie:
haben %Vor% Damit können Sie in die Tabelle STAGE_NODE
importieren, wobei die importierten Schlüsselwerte beibehalten werden. Der Einfügeprozess setzt die ursprüngliche ID aus der importierten Tabelle in STAGED_ID und füllt die ID aus der Sequenz.
Stellen Sie sicher, dass Sie die gleiche Sequenz verwenden verwendet, um die ID-Spalte in zu füllen die Zieltabelle. Dies stellt sicher, dass Sie nicht bekomme Schlüsselkollisionen wenn du gehst Einfügen in die endgültige Zieltabelle. Es ist wichtig, die gleiche Sequenz zu verwenden.
Als nützlicher Nebeneffekt ermöglicht dies auch den Import, während andere Operationen auf dem Tisch stattfinden; gleichzeitige Lesevorgänge in einer einzelnen Sequenz sind in Ordnung. Bei Bedarf können Sie diese Art des Importvorgangs ausführen, ohne die Anwendung herunter zu fahren.
Sobald Sie diese Zuordnung in der Staging-Tabelle haben, sind ID-Werte in der EDGE-Tabelle trivial, um sie mit einer Abfrage wie:
zu berechnen %Vor%Die gemappten EDGE-Werte können mit einer UPDATE-Abfrage mit einem ähnlichen Join wieder in die Staging-Tabellen eingefügt oder aus einer Abfrage ähnlich der obigen direkt in die Zieltabelle eingefügt werden.
Ich habe diese Art von Dingen oft gemacht, aber mein Gedächtnis ist ein bisschen verschwommen. Ich werde dir die allgemeine Idee geben, hoffe, dass sie dich in die richtige Richtung weisen kann.
Grundsätzlich können Sie das nur tun, wenn Sie in der 'Eltern' -Tabelle eine zuverlässige zweite Spalte mit 'einmaligem Schlüssel' haben. Wenn nicht, müssen Sie eine erstellen.
Sagen wir, wir haben diese Tabellen
%Vor%Sie möchten zunächst ITEMS von SOURCEDB nach TARGETDB kopieren und TARGETDB eigene Werte für die ID-Spalte erstellen lassen.
Dann müssen Sie HIERARCHY von SOURCEDB nach TARGETDB kopieren, aber Sie müssen einen Join machen, um die neue ID zu erhalten:
%Vor%Und Sie müssen die gleiche Sache für die idchild Spalte tun.
Dies wird so etwas geben (ungetestet und rostig und wahrscheinlich mssql-Syntax):
%Vor%Ich nehme an, dass diese beiden Datenbanken so "verbunden" sind, dass Sie datenbankübergreifende Abfragen durchführen können. Wenn Sie in eine Datei serialisieren müssen, wird es ein bisschen komplizierter.
Sie können erreichen, was Sie benötigen, indem Sie eine temporäre Tabelle in der Zieldatenbank verwenden. Da IDs automatisch generiert werden, erzeugt der folgende Code keine Kollisionen.
Ich gehe davon aus, dass die Quellendatenbank SourceDb heißt und die Zieldatenbank TargetDb heißt.
Ich werde auch diese Tabellenstruktur annehmen:
Begriffe : ID , Text
Beziehungen : ParentId , Kind-ID
Erstellen Sie eine temporäre Tabelle in TargetDb mit dieser Struktur:
TempTerms : OldId , Text , OldParentId , NewId , NewParentId
Der folgende Code kopiert Ihren Teilbaum in die Zieldatenbank.
%Vor%Wie wäre es, die Daten als XML weiterzugeben? Es ist natürlich so konzipiert, dass es mit Baumstrukturen funktioniert, und viele DBMS enthalten eine gute Unterstützung für das Parsen und Konvertieren von XML.
Sie müssen sicherstellen, dass der Knoten X in DB1 dem Knoten Y in DB 2 zugeordnet ist, aber dafür sollten Sie eine Tatsache über den Knoten (einen Namen usw.) hinter dem Primärschlüssel verwenden.
Sie können die Schlüssel für jeden DB auch um einen regulären Betrag (zB 2 ^ 32) versetzen und eine BIG INTEGER-Taste verwenden. Begrenzt Einträge auf 2 ^ 32, aber immer noch hilfreich.
(Ich mag die Frage hier falsch verstehen, aber ich hoffe nicht.)