Najlepszy sposób synchronizacji danych między dwiema różnymi bazami danych

24

Muszę wdrożyć synchronizację danych między dwiema dużymi bazami danych, które mają zupełnie inne struktury. Zasadniczo muszę wykreślić niektóre dane dotyczące produktów w różnych tabelach w pierwszej bazie danych i ponownie ustawić je dla innych tabel w drugiej bazie danych.

Tworzenie moich produktów po raz pierwszy nie jest bardzo skomplikowane. Ale szukam sposobu na aktualizację niektórych konkretnych danych - nie wszystkich danych - o każdym produkcie.

Oczywiście jest kilka problemów, które sprawiają, że jest to trudne.

  • Nie wolno mi nic robić w źródłowej bazie danych oprócz wybierania zapytań.
  • W docelowej bazie danych mogę wykonywać zwykłe zapytania (wybierać, aktualizować, wstawiać, tworzyć), ale nie mogę modyfikować istniejącej struktury / tabel.
  • Docelowa i źródłowa baza danych mają zupełnie inne struktury, tabele wcale nie są takie same, dlatego dane naprawdę muszą zostać uporządkowane - porównywanie tabel nie będzie działać.
  • Docelowa baza danych korzysta z serwera MySQL - źródłem może być DB2.
  • Nigdzie nie ma pól „zaktualizowany czas”.

Cały proces musi więc zostać przeprowadzony w jednym (najlepiej) skrypcie w języku Python.

Myślę o stworzeniu skrótu dla każdego produktu na podstawie pól do aktualizacji w docelowej bazie danych: md5 (kod + opis + dostawca + około 10 innych pól). Nowy skrót na podstawie tych samych danych będzie tworzony codziennie ze źródłowej bazy danych. Będę przechowywać wszystkie skróty w jednej tabeli (kod elementu, bieżący skrót, stary skrót) w celu wykonania. Następnie porównaj i zaktualizuj produkt, jeśli nowy skrót różni się od starego.

Istnieje około 500 000 produktów, więc trochę się martwię o występy.

Czy to dobra droga?

Neow
źródło
2
Czy oni też chcą, żebyś to zrobił z zasłoniętymi oczami? To teraz mój problem ...
Kapitan Hypertext
1
@ Nowość, jak poszło? Jakieś porady, które możesz teraz zaoferować?
Edwin Evans
4
@EdwinEvans zasadniczo pozostałem z moim pierwszym pomysłem, ale szczególnie z powodu ograniczeń, które miałem. Mój skrypt tworzy skróty md5 na podstawie kluczowych danych dla wszystkich elementów. Następnie porównuję z poprzednimi hashami. Jeśli skróty są różne, ładuje wszystkie dane elementu i aktualizuje wszystko. Nie jestem pewien, czy to najlepszy sposób, ale działa w nocy, a występy są przyzwoite.
Neow

Odpowiedzi:

9

To jest prawie to, co robiłem lub żyję w ciągu ostatnich kilku lat, a mój instynkt podpiera się tym, że czas na odczytanie 500 000 pozycji ze źródłowej bazy danych i synchronizację w miejscu docelowym nie zajmie tyle czasu, ile mogłoby się wydawać, a czas poświęcony na odczytanie pól „klucza”, obliczenie skrótu MD5 i sprawdzenie krzyżowe tabeli, aby uniknąć synchronizacji elementów, które nie uległy zmianie, ostatecznie nie oszczędzają zbyt wiele czasu, a nawet mogą działać dłużej. Po prostu przeczytam wszystko i zaktualizuję wszystko. Jeśli to spowoduje, że środowisko wykonawcze będzie zbyt długie, skompresuję środowisko wykonawcze, tworząc ET-muti z wątkami, przy czym każdy wątek działa tylko na segmencie tabeli, ale działa równolegle.

Ważne jest, aby upewnić się, że docelowa baza danych ma indeks klucza podstawowego lub indeks unikalny. W przeciwnym razie każda z twoich aktualizacji / wstawek może zablokować cały stół. Byłoby to złe, jeśli przyjmujesz podejście wielowątkowe, ale ważne, nawet jeśli pozostajesz jednowątkowy, ponieważ twoje zadanie może zablokować docelową tabelę DB i zakłócać aplikację, która jest na wierzchu tego DB.

Mówisz, że źródłowa baza danych „może być DB2”. Kiedy mówisz „może”, oznacza to, że DB jest nadal projektowane / planowane? Program DB2 9 lub nowszy ma wbudowane śledzenie czasu ostatniej aktualizacji oraz możliwość zapytania i odzyskania tylko elementów, które zmieniły się od czasu. Być może dlatego DB zaprojektowano tak, aby nie zawierała kolumny wskazującej czas ostatniej aktualizacji, np .:

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

Wartość graniczna znacznika czasu dla powyższego zapytania byłaby ostatnim znacznikiem czasu uruchomionym przez synchronizację.

W takim przypadku powinno to rozwiązać problem. Ale Twoje rozwiązanie byłoby bardzo ściśle powiązane z DB2, aw przyszłości mogą chcieć przejść na inną platformę DB i oczekiwać, że Twoje zadanie synchronizacji nie będzie musiało być ponownie odwiedzane. Dlatego ważne jest, aby upewnić się, że wszystkie właściwe osoby wiedzą, że Twój produkt będzie zależał od pozostania w programie DB2, lub jeśli planują migrację, migracja obejmowałaby restrukturyzację bazy danych, tak aby zawierała kolumnę „ostatnia zmiana znacznika czasu”, i cokolwiek zmiany konieczne na poziomie aplikacji, aby wypełnić to pole.

Thomas Carlisle
źródło
czy istnieje również podobne rozwiązanie dla mysql?
Fardin Behboudi
5

Synchronizacja danych byłaby znacznie lepsza i szybsza, gdyby można to zrobić na podstawie pewnego rodzaju identyfikatora delty lub flagi. Zasadniczo należy aktualizować docelowe wiersze danych bazy danych tylko wtedy, gdy nie są zsynchronizowane ze źródłową bazą danych.

W SQL Server db można skorzystać z pomocy sumy kontrolnej fn, aby zbudować identyfikator oparty na delcie.

Powinieneś opracować zadanie oparte na SQL, aby było wywoływane o określonej porze dnia lub nocy, aby uruchomić tę logikę SQL. Lepiej jest uruchomić go jako nocne zadanie SQL, gdy użycie bazy danych jest bardzo niskie. Jeśli delta źródłowego i docelowego rekordu db nie jest zgodna, wyciągnij tylko te rekordy. Minusem byłoby jednak obliczenie sumy kontrolnej wierszy danych źródłowych za każdym razem, a następnie porównanie jej z danymi docelowymi.

Jeśli masz kolumnę typu „LastModifiedDate” w źródłowych tabelach db, możesz pominąć podejście do sumy kontrolnej. W ten sposób ocena zostanie wykonana w kolumnie opartej na dacie i zajmuje mniej czasu w porównaniu do metody sumy kontrolnej.

Karan
źródło
Dzięki, ale nie jestem pewien, czy Twoje rozwiązanie może działać - zobacz moje zmiany w części „Problemy”.
Neow
Ponieważ w źródłowej bazie danych nie ma zaktualizowanych pól czasu, możemy pobrać kwalifikowane wiersze danych na podstawie sumy kontrolnej lub wartości skrótu.
Karan
Ponieważ źródłem jest db2. Jak zamierzasz wyciągać z niego dane? za pośrednictwem jakiegoś serwisu internetowego lub API ..
Karan
DSN został skonfigurowany przy użyciu sterownika odbc. Mogę łączyć się i wykonywać zapytania za pomocą pyodbc dla Pythona.
Neow
W porządku, to dobrze, ponieważ można wykonywać zapytania za pomocą narzędzia o nazwie PyODBC do zdalnego DB. Możesz zrobić jeszcze jedną rzecz. Możesz pobrać dane produktu prosto w tym samym formacie, w jakim są, do nowej „tabeli pomostowej” w docelowej bazie danych bez żadnych kontroli ani weryfikacji. W ten sposób otrzymujesz dane na żywo w jednym ujęciu w docelowej bazie danych pod tabelami stołu montażowego. Następnie w drugim kroku możesz wykonać operacje sumy kontrolnej i zaktualizować dane docelowej tabeli transakcyjnej. Pozwoliłoby to uniknąć oceny skrótu lub sumy kontrolnej ze źródłowymi danymi db w czasie rzeczywistym.
Karan
1

Używanie skrótu jest dobrym pomysłem. Ponieważ bezpieczeństwo nie jest celem w tym przypadku, wybierz funkcję skrótu, która jest szybka (md5 jest w porządku).

O ile nie planujesz podzielić obliczeń skrótu na wiele wątków / procesów, tak naprawdę nie musisz przechowywać bieżącej wartości skrótu w bazie danych. Jeśli twój proces jest pojedynczym skryptem, po prostu będziesz mieć bieżący skrót w pamięci i zapisze go w bazie danych jako stary skrót po zaktualizowaniu danych w nowej bazie danych.

Kent A.
źródło
-1

powinieneś utworzyć usługę systemu Windows, która będzie działała w określonych momentach, kiedy tylko zechcesz, a ona znajdzie zmiany w źródłowej bazie danych i wstawi te zmiany do docelowej bazy danych.

manish kumar
źródło
-1 (tak naprawdę nie głosował, ale;) tylko dla sugestii Windows. nie opierajmy się na żadnej konkretnej architekturze podczas tworzenia oprogramowania, to po prostu oznacza, że ​​tylko kilka osób może korzystać z twoich rzeczy. jedyną stałą jest zmiana, więc lepiej nie polegać na żadnej konkretnej platformie w stopniu, który ułatwia utrzymanie jej dla siebie i użytkowników
pythonian29033
1
@manish kumar część „znajdzie zmiany w źródłowej bazie danych” jest najtrudniejsza!
Narvalex,