Beste Möglichkeit zum Synchronisieren von Daten zwischen zwei verschiedenen Datenbanken

24

Ich muss die Datensynchronisation zwischen zwei großen Datenbanken implementieren, die völlig unterschiedliche Strukturen haben. Grundsätzlich muss ich einige Daten zu Produkten in verschiedenen Tabellen in der ersten Datenbank erfassen und sie für andere Tabellen in der zweiten Datenbank neu anordnen.

Das erstmalige Erstellen meiner Produkte ist nicht sehr kompliziert. Ich suche jedoch nach einer Möglichkeit, bestimmte Daten - nicht alle Daten - zu jedem Produkt zu aktualisieren.

Offensichtlich gibt es ein paar Probleme, die dies schwierig machen.

  • Abgesehen von ausgewählten Abfragen darf ich in der Quelldatenbank nichts tun.
  • In der Zieldatenbank kann ich übliche Abfragen ausführen (auswählen, aktualisieren, einfügen, erstellen), die vorhandene Struktur / die vorhandenen Tabellen können jedoch nicht geändert werden.
  • Ziel- und Quelldatenbank haben völlig unterschiedliche Strukturen, Tabellen sind überhaupt nicht gleich, daher müssen die Daten wirklich neu angeordnet werden - das Vergleichen von Tabellen funktioniert nicht.
  • Die Zieldatenbank verwendet einen MySQL-Server. Die Quelle ist möglicherweise DB2.
  • Es gibt nirgendwo "aktualisierte Zeit" Felder.

Der gesamte Vorgang muss also (im Idealfall) in einem einzigen Python-Skript ausgeführt werden.

Ich denke darüber nach, einen Hash für jedes Produkt zu erstellen, basierend auf den zu aktualisierenden Feldern in der Zieldatenbank: md5 (Code + Beschreibung + Lieferant + ungefähr 10 andere Felder). Ein neuer Hash, der auf denselben Daten basiert, wird täglich aus der Quellendatenbank erstellt. Ich werde alle Hashes in einer einzigen Tabelle (Artikelcode, current_hash, old_hash) für Leistungszwecke speichern. Vergleichen und aktualisieren Sie dann das Produkt, wenn sich der neue Hash vom alten unterscheidet.

Es gibt ungefähr 500 000 Produkte, also mache ich mir ein bisschen Sorgen um die Leistung.

Ist es der richtige Weg?

Neow
quelle
2
Wollen sie, dass du es auch mit verbundenen Augen tust? Das ist jetzt mein Problem ...
Captain Hypertext
1
@Neow, wie ist es gelaufen? Irgendwelche Ratschläge, die Sie jetzt anbieten können?
Edwin Evans
4
@EdwinEvans Im Grunde bin ich bei meiner ersten Idee geblieben, aber vor allem aufgrund von Einschränkungen, die ich hatte. Mein Skript erstellt MD5-Hashes basierend auf Schlüsseldaten für alle Elemente. Dann vergleiche ich mit früheren Hashes. Wenn die Hashes unterschiedlich sind, werden alle Daten für den Artikel geladen und alles aktualisiert. Ich bin nicht sicher, ob dies der beste Weg ist, aber es läuft nachts und die Leistungen sind anständig.
Neow

Antworten:

9

Dies ist so ziemlich das, was ich in den letzten Jahren gemacht oder gelebt habe, und mein Bauchgefühl ist, dass die Zeit zum Lesen von 500.000 Elementen aus der Quellendatenbank und zum Synchronisieren im Ziel nicht so lange dauern wird, wie man denkt Die Zeit, die zum Lesen der "Schlüsselfelder", zum Berechnen des MD5-Hashs und zum Abgleichen mit Ihrer Tabelle benötigt wird, um zu vermeiden, dass nicht geänderte Elemente synchronisiert werden, spart nicht allzu viel Zeit und kann sogar länger dauern. Ich würde einfach alles lesen und alles aktualisieren. Wenn dies zu einer zu langen Laufzeit führt, würde ich die Laufzeit komprimieren, indem ich die ETL auf mehrere Threads verteile, wobei jeder Thread nur in einem Segment der Tabelle ausgeführt wird, aber parallel arbeitet.

Es wäre wichtig, sicherzustellen, dass Ihre Zieldatenbank einen Primärschlüsselindex oder einen eindeutigen Index hat. Andernfalls kann jede Ihrer Aktualisierungen / Einfügungen die gesamte Tabelle sperren. Dies wäre schlecht, wenn Sie den Multithread-Ansatz verwenden, aber wichtig, auch wenn Sie Single-Threading beibehalten, da Ihr Job die Ziel-DB-Tabelle sperren und die Anwendung beeinträchtigen könnte, die auf dieser DB ausgeführt wird.

Sie sagen, dass die Quellendatenbank "DB2 sein kann". Wenn Sie "kann" sagen, bedeutet dies, dass die Datenbank noch entworfen / geplant wird? DB2 9 oder höher verfügt über eine integrierte Nachverfolgung der letzten Aktualisierung und die Möglichkeit, nur die Elemente abzufragen und zurückzugewinnen, die sich seit einem bestimmten Zeitpunkt geändert haben. Möglicherweise wurde die Datenbank deshalb so konzipiert, dass sie keine Spalte enthält, in der die letzte aktualisierte Zeit angegeben ist. Beispiel:

SELECT * FROM T1 WHERE ROW CHANGE TIMESTAMP FOR TAB t1 > current timestamp - 1 hours;

Der Zeitstempel-Cutoff für die obige Abfrage ist der letzte Zeitstempel, den Ihre Synchronisierung ausgeführt hat.

Wenn dies der Fall ist, sollte das Ihr Problem lösen. Ihre Lösung ist jedoch sehr eng mit DB2 verbunden, und in Zukunft möchten sie möglicherweise auf eine andere DB-Plattform umsteigen und erwarten, dass Ihr Synchronisierungsjob nicht erneut besucht werden muss. Es ist daher wichtig, sicherzustellen, dass alle richtigen Personen wissen, dass Ihr Produkt von der Verfügbarkeit von DB2 abhängig ist, oder dass bei einer geplanten Migration die Datenbank so umstrukturiert wird, dass die Spalte "Zuletzt geänderter Zeitstempel" angezeigt wird Änderungen, die auf App-Ebene erforderlich sind, um dieses Feld auszufüllen.

Thomas Carlisle
quelle
gibt es eine ähnliche lösung für mysql auch?
Fardin Behboudi
5

Die Datensynchronisation wäre viel besser und schneller, wenn sie auf der Basis einer Delta-Kennung oder eines Delta-Flags erfolgen könnte. Grundsätzlich sollten Sie die Ziel-DB-Datenzeilen nur aktualisieren, wenn sie nicht mit der Quell-DB synchron sind.

In SQL Server DB können Sie mithilfe der Prüfsumme fn auch den Delta-basierten Bezeichner erstellen.

Sie sollten einen SQL-basierten Job entwickeln , der zu einer bestimmten Tages- oder Nachtzeit aufgerufen wird, damit diese SQL-Logik ausgelöst wird. Es ist besser, es als nächtlichen SQL-Job auszuführen, wenn die Datenbankauslastung sehr gering ist. Wenn das Delta der Quell- und Ziel-DB-Datensätze nicht übereinstimmt, ziehen Sie nur diese Datensätze. Der Nachteil wäre jedoch, jedes Mal die Prüfsumme der Quelldatenzeilen zu berechnen und sie dann mit den Zieldaten zu vergleichen.

Wenn Sie eine Spalte wie "LastModifiedDate" in den Quell-DB-Tabellen haben, können Sie den Prüfsummenansatz überspringen. Auf diese Weise wird Ihre Bewertung für die datumsbasierte Spalte ausgeführt und nimmt im Vergleich zum Prüfsummenansatz weniger Zeit in Anspruch.

Karan
quelle
Vielen Dank, aber ich bin nicht sicher, ob Ihre Lösung funktionieren könnte - siehe meine Änderungen im Abschnitt "Probleme".
Neow
Da in der Quellendatenbank keine aktualisierten Zeitfelder vorhanden sind, müssen wir die qualifizierten Datenzeilen basierend auf der Prüfsumme oder dem Hash abrufen.
Karan
Da deine Quelle db2 ist. Wie wollen Sie die Daten daraus ziehen? über einen Webservice oder API ..
Karan
Ein DNS wurde mit einem ODBC-Treiber eingerichtet. Ich kann mit pyodbc für Python eine Verbindung herstellen und Abfragen durchführen.
Neow
Das ist in Ordnung, da Sie die Abfragen mit dem Tool PyODBC in der entfernten Datenbank ausführen können. Sie können noch etwas tun. Sie können die Produktdaten direkt in demselben Format wie sie sind in die neue "Staging-Tabelle" in Ihrer Ziel-DB ziehen, ohne dass Überprüfungen oder Validierungen erforderlich sind. Auf diese Weise erhalten Sie die Live-Daten in einer einzigen Aufnahme in Ihrer Ziel-DB unter den Bühnentabellen. Später im zweiten Schritt können Sie dann die Prüfsummenoperationen ausführen und die Daten der Zieltransaktionstabelle aktualisieren. Dies würde die Hash- oder Prüfsummenauswertung mit den Quell-DB-Daten in Echtzeit verhindern.
Karan
1

Die Verwendung eines Hashs ist eine gute Idee. Da in diesem Fall die Sicherheit nicht das Ziel ist, wählen Sie eine schnelle Hash-Funktion (md5 ist in Ordnung).

Sofern Sie nicht vorhaben, die Hash-Berechnung auf mehrere Threads / Prozesse aufzuteilen, müssen Sie den aktuellen Hash-Wert nicht wirklich in der Datenbank speichern. Wenn es sich bei Ihrem Prozess um ein einzelnes Skript handelt, wird nur der aktuelle Hash im Speicher abgelegt und nach der Aktualisierung der Daten in der neuen Datenbank als alter Hash in die Datenbank geschrieben.

Kent A.
quelle
-1

Sie sollten einen Windows-Dienst erstellt haben, der zu bestimmten Zeiten ausgeführt wird, wann immer Sie möchten, und der die Änderungen in Ihrer Quellendatenbank findet und diese Änderungen in Ihre Zieldatenbank einfügt.

manish kumar
quelle
-1 (nicht wirklich schlecht bewertet, aber;) für Windows nur Vorschlag. Verlassen wir uns bei der Entwicklung von Software nicht auf eine bestimmte Architektur, sondern nur auf einige wenige Benutzer. Die einzige Konstante ist der Wandel.
Daher
1
@manish kumar der Teil "es wird die Änderungen in Ihrer Quellendatenbank finden" ist der schwierigste!
Narvalex