Exportieren / Importieren eines hierarchischen Diagramms aus einer Datenbank

8

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 ...

    
PaulJWilliams 26.01.2010, 15:53
quelle

5 Antworten

3

Ü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:

  • Begriffe mit identischem Text können zusammengefügt werden

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:

  • Begriffe mit demselben Text müssen eindeutig sein und
  • Sie können der Zieltabelle eine Spalte hinzufügen

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:

  • Begriffe mit demselben Text müssen eindeutig sein und
  • Sie können die Zieltabelle und
  • nicht ändern
  • Entweder (a) Ihre ID-Spalte ist eine Identitätsspalte (in Oracle bedeutet dies, dass sie über einen Trigger verfügt, der eine Sequenz verwendet) oder (b) eine allgemeine Methode, die mit jeder Datenbanktechnologie funktioniert

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:

  • Begriffe mit demselben Text müssen eindeutig sein und
  • Sie können die Zieltabelle und
  • nicht ändern
  • Sie haben Zugriff auf die Sequenz, die Ihre ID-Spalte generiert, und
  • Sie können eine Technik verwenden, die nicht auf eine Nicht-Oracle-Datenbanktechnologie portiert

Im Folgenden werden alle Begriffe und Beziehungen von A in B zusammengeführt:

%Vor%     
Ray Burns 29.01.2010, 18:26
quelle
5

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.

    
quelle
0

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.

    
Benjol 29.01.2010 14:34
quelle
0

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%     
Aaron 29.01.2010 14:35
quelle
0

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.)

    
BobMcGee 02.02.2010 01:43
quelle

Tags und Links