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


24

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

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

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

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

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

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

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

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


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 часть "он найдет изменения в вашей исходной базе данных" - самая трудная!
— Нарвалекс
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.