Лучший способ синхронизировать данные между двумя разными базами данных

24

Я должен реализовать синхронизацию данных между двумя большими базами данных, которые имеют совершенно разные структуры. По сути, мне нужно собрать некоторые данные о продуктах в разных таблицах в первой базе данных и перегруппировать их для других таблиц во второй базе данных.

Создание моих продуктов с первого раза не очень сложно. Но я ищу способ обновить некоторые конкретные данные - не все данные - о каждом продукте.

Очевидно, есть несколько проблем, которые делают это сложно.

  • Мне не разрешено ничего делать с исходной базой данных, кроме запросов выбора.
  • В целевой базе данных я могу выполнять обычные запросы (выбрать, обновить, вставить, создать), но не могу изменить существующую структуру / таблицы.
  • Target и source db имеют совершенно разные структуры, таблицы совсем не одинаковы, поэтому данные действительно нужно переставлять - сравнение таблиц не будет работать.
  • Целевая база данных использует сервер MySQL - источником может быть DB2.
  • Поля "обновленного времени" нигде нет.

Таким образом, весь процесс должен быть выполнен в одном скрипте Python (в идеале).

Я думаю о создании хэша для каждого продукта на основе полей, которые необходимо обновить в целевой базе данных: md5 (код + описание + поставщик + около 10 других полей). Новый хэш, основанный на тех же данных, будет создаваться ежедневно из исходной базы данных. Я буду хранить все хэши в одной таблице (код элемента, current_hash, old_hash) для целей производительности. Затем сравните и обновите продукт, если новый хеш отличается от старого.

Есть около 500 000 продуктов, так что я немного беспокоюсь о производительности.

Это хороший путь?

Neow
источник
2
Они хотят, чтобы ты тоже делал это с завязанными глазами? Это моя проблема прямо сейчас ...
Капитан Гипертекст
1
@ Теперь, как все прошло? Какой совет вы можете предложить сейчас?
Эдвин Эванс
4
@ EdwinEvans, в основном, я остался с моей первой идеей, но особенно из-за ограничений, которые у меня были. Мой скрипт создает хэши md5 на основе ключевых данных для всех элементов. Затем я сравниваю с предыдущими хешами. Если хэши разные, тогда он загружает все данные для элемента и обновляет все. Не уверен, что это самый лучший способ, но он работает ночью и приличные выступления.
Сейчас

Ответы:

9

Это в значительной степени то, чем я занимался или зарабатывал последние несколько лет, и мой инстинкт инстинкта заключается в том, что время для чтения 500 000 элементов из исходной базы данных и синхронизации в месте назначения не займет столько времени, сколько можно подумать, и Время, затраченное на чтение «ключевых» полей, вычисление хэша MD5 и перекрестную проверку с вашей таблицей, чтобы избежать синхронизации элементов, которые не изменились, не приведет к экономии слишком большого количества времени и даже может занять больше времени. Я просто прочитал бы все и обновил бы все. Если это приводит к слишком длительному времени выполнения, то я бы сжал время выполнения, сделав многопоточность ETL, причем каждый поток работает только в сегменте таблицы, но работает параллельно.

Было бы важно убедиться, что у вашей целевой базы данных есть индекс первичного ключа или уникальный индекс. В противном случае каждое из ваших обновлений / вставок может заблокировать всю таблицу. Это было бы плохо, если вы используете многопоточный подход, но важно, даже если вы остаетесь однопоточным, потому что ваша работа может заблокировать таблицу назначения БД и помешать работе приложения, которое работает поверх этой БД.

Вы говорите, что исходная БД "может быть DB2". Когда вы говорите «может», это означает, что БД все еще разрабатывается / планируется? DB2 9 или выше имеет встроенное отслеживание времени последнего обновления и возможность запрашивать и возвращать только те элементы, которые изменились с того момента времени. Возможно, именно поэтому БД была разработана таким образом, чтобы в ней не было столбца с указанием времени последнего обновления, например:

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

Обрезка временной метки для вышеупомянутого запроса будет последней отметкой времени вашей синхронизации.

Если это так, то это должно решить вашу проблему. Но ваше решение в конечном итоге будет очень тесно связано с DB2, и в будущем они могут захотеть перейти на другую платформу БД и ожидать, что ваше задание синхронизации не нужно будет повторно посещать. Поэтому было бы важно убедиться, что все правильные люди знают, что ваш продукт будет зависеть от того, останется ли он в DB2, или если они планируют перенастроить эту миграцию, потребуется реструктурировать БД, чтобы иметь столбец «последняя измененная временная метка», и делать все, что угодно. изменения, необходимые на уровне приложения, чтобы заполнить это поле.

Томас Карлайл
источник
Есть ли подобное решение для MySQL тоже?
Фардин Бехбуди
5

Синхронизация данных была бы намного лучше и быстрее, если бы это можно было сделать на основе какого-либо дельта-идентификатора или флага. По сути, вы должны обновлять строки данных целевой базы данных только тогда, когда они не синхронизированы с исходной базой данных.

В базе данных SQL server db вы также можете воспользоваться контрольной суммой fn для создания идентификатора на основе дельты.

Вы должны разработать работу на основе SQL, чтобы вызывать ее в определенное время дня или ночи, чтобы запустить эту логику sql. Лучше запускать его как ночное задание SQL, когда использование базы данных очень мало. Если различие между исходной и целевой записями базы данных не совпадает, извлекайте только эти записи. Но недостатком будет каждый раз вычислять контрольную сумму строк исходных данных, а затем сравнивать ее с целевыми данными.

Если у вас есть столбец типа «LastModifiedDate» в исходных таблицах БД, то вы можете пропустить подход с контрольной суммой. Таким образом, ваша оценка будет выполнена в столбце на основе даты и займет меньше времени по сравнению с подходом контрольной суммы.

Каран
источник
Спасибо, но я не уверен, что ваше решение могло бы сработать - посмотрите мои правки в разделе "Проблемы".
Сейчас
Поскольку в исходной базе данных нет обновленных полей времени, нам остается извлечь строки квалифицированных данных на основе контрольной суммы или хэша.
Каран
Так как ваш источник db2. Как вы собираетесь извлечь данные из него? через какой-либо веб-сервис или API ..
Каран
DSN был настроен с использованием драйвера odbc. Я могу подключаться и делать запросы, используя pyodbc для Python.
Сейчас
Хорошо, это хорошо, так как вы можете выполнять запросы, используя инструмент под названием PyODBC, в удаленную БД. Вы можете сделать еще одну вещь. Вы можете вытащить данные продукта прямо в том же формате, что и в новую «промежуточную таблицу» в целевой БД, без каких-либо проверок или проверок. Таким образом, вы получите живые данные за один раз в вашей целевой БД под таблицами этапов. Затем на втором шаге вы можете выполнить операции с контрольной суммой и обновить данные целевой таблицы транзакций. Это предотвратит оценку хэша или контрольной суммы с исходными данными в реальном времени.
Каран
1

Использование хэша - хорошая идея. Поскольку в данном случае безопасность не является целью, выбирайте быструю хеш-функцию (хорошо, md5).

Если вы не планируете разделять вычисление хеша на несколько потоков / процессов, вам не нужно хранить текущее значение хеша в базе данных. Если ваш процесс представляет собой один скрипт, у вас будет только текущий хеш в памяти, и вы запишете его в базу данных как старый хеш после обновления данных в новой базе данных.

Кент А.
источник
-1

вам нужно создать службу Windows, которая будет запускаться в определенное время, когда вы захотите, и она найдет изменения в вашей исходной базе данных и вставит эти изменения в вашу целевую базу данных.

маниш кумар
источник
-1 (на самом деле не понизило голосование, но;) для окон только предложение. давайте не будем полагаться на какую-либо конкретную архитектуру при разработке программного обеспечения, это просто означает, что только несколько человек могут использовать ваши вещи. единственная константа - это изменение, и поэтому лучше не полагаться на какую-либо конкретную платформу в той степени, которая упрощает обслуживание для вас и пользователей
pythonian29033
1
@manish kumar часть "он найдет изменения в вашей исходной базе данных" - самая трудная!
Нарвалекс