Я должен реализовать синхронизацию данных между двумя большими базами данных, которые имеют совершенно разные структуры. По сути, мне нужно собрать некоторые данные о продуктах в разных таблицах в первой базе данных и перегруппировать их для других таблиц во второй базе данных.
Создание моих продуктов с первого раза не очень сложно. Но я ищу способ обновить некоторые конкретные данные - не все данные - о каждом продукте.
Очевидно, есть несколько проблем, которые делают это сложно.
- Мне не разрешено ничего делать с исходной базой данных, кроме запросов выбора.
- В целевой базе данных я могу выполнять обычные запросы (выбрать, обновить, вставить, создать), но не могу изменить существующую структуру / таблицы.
- Target и source db имеют совершенно разные структуры, таблицы совсем не одинаковы, поэтому данные действительно нужно переставлять - сравнение таблиц не будет работать.
- Целевая база данных использует сервер MySQL - источником может быть DB2.
- Поля "обновленного времени" нигде нет.
Таким образом, весь процесс должен быть выполнен в одном скрипте Python (в идеале).
Я думаю о создании хэша для каждого продукта на основе полей, которые необходимо обновить в целевой базе данных: md5 (код + описание + поставщик + около 10 других полей). Новый хэш, основанный на тех же данных, будет создаваться ежедневно из исходной базы данных. Я буду хранить все хэши в одной таблице (код элемента, current_hash, old_hash) для целей производительности. Затем сравните и обновите продукт, если новый хеш отличается от старого.
Есть около 500 000 продуктов, так что я немного беспокоюсь о производительности.
Это хороший путь?
Ответы:
Это в значительной степени то, чем я занимался или зарабатывал последние несколько лет, и мой инстинкт инстинкта заключается в том, что время для чтения 500 000 элементов из исходной базы данных и синхронизации в месте назначения не займет столько времени, сколько можно подумать, и Время, затраченное на чтение «ключевых» полей, вычисление хэша MD5 и перекрестную проверку с вашей таблицей, чтобы избежать синхронизации элементов, которые не изменились, не приведет к экономии слишком большого количества времени и даже может занять больше времени. Я просто прочитал бы все и обновил бы все. Если это приводит к слишком длительному времени выполнения, то я бы сжал время выполнения, сделав многопоточность ETL, причем каждый поток работает только в сегменте таблицы, но работает параллельно.
Было бы важно убедиться, что у вашей целевой базы данных есть индекс первичного ключа или уникальный индекс. В противном случае каждое из ваших обновлений / вставок может заблокировать всю таблицу. Это было бы плохо, если вы используете многопоточный подход, но важно, даже если вы остаетесь однопоточным, потому что ваша работа может заблокировать таблицу назначения БД и помешать работе приложения, которое работает поверх этой БД.
Вы говорите, что исходная БД "может быть DB2". Когда вы говорите «может», это означает, что БД все еще разрабатывается / планируется? DB2 9 или выше имеет встроенное отслеживание времени последнего обновления и возможность запрашивать и возвращать только те элементы, которые изменились с того момента времени. Возможно, именно поэтому БД была разработана таким образом, чтобы в ней не было столбца с указанием времени последнего обновления, например:
Обрезка временной метки для вышеупомянутого запроса будет последней отметкой времени вашей синхронизации.
Если это так, то это должно решить вашу проблему. Но ваше решение в конечном итоге будет очень тесно связано с DB2, и в будущем они могут захотеть перейти на другую платформу БД и ожидать, что ваше задание синхронизации не нужно будет повторно посещать. Поэтому было бы важно убедиться, что все правильные люди знают, что ваш продукт будет зависеть от того, останется ли он в DB2, или если они планируют перенастроить эту миграцию, потребуется реструктурировать БД, чтобы иметь столбец «последняя измененная временная метка», и делать все, что угодно. изменения, необходимые на уровне приложения, чтобы заполнить это поле.
источник
Синхронизация данных была бы намного лучше и быстрее, если бы это можно было сделать на основе какого-либо дельта-идентификатора или флага. По сути, вы должны обновлять строки данных целевой базы данных только тогда, когда они не синхронизированы с исходной базой данных.
В базе данных SQL server db вы также можете воспользоваться контрольной суммой fn для создания идентификатора на основе дельты.
Вы должны разработать работу на основе SQL, чтобы вызывать ее в определенное время дня или ночи, чтобы запустить эту логику sql. Лучше запускать его как ночное задание SQL, когда использование базы данных очень мало. Если различие между исходной и целевой записями базы данных не совпадает, извлекайте только эти записи. Но недостатком будет каждый раз вычислять контрольную сумму строк исходных данных, а затем сравнивать ее с целевыми данными.
Если у вас есть столбец типа «LastModifiedDate» в исходных таблицах БД, то вы можете пропустить подход с контрольной суммой. Таким образом, ваша оценка будет выполнена в столбце на основе даты и займет меньше времени по сравнению с подходом контрольной суммы.
источник
Использование хэша - хорошая идея. Поскольку в данном случае безопасность не является целью, выбирайте быструю хеш-функцию (хорошо, md5).
Если вы не планируете разделять вычисление хеша на несколько потоков / процессов, вам не нужно хранить текущее значение хеша в базе данных. Если ваш процесс представляет собой один скрипт, у вас будет только текущий хеш в памяти, и вы запишете его в базу данных как старый хеш после обновления данных в новой базе данных.
источник
вам нужно создать службу Windows, которая будет запускаться в определенное время, когда вы захотите, и она найдет изменения в вашей исходной базе данных и вставит эти изменения в вашу целевую базу данных.
источник