Найкращий спосіб синхронізації даних між двома різними базами даних


24

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

Створення моїх продуктів у перший раз не дуже складно. Але я шукаю спосіб оновити деякі конкретні дані - не всі дані - про кожен продукт.

Очевидно, є кілька питань, які роблять це хитро.

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

Тому весь процес потрібно провести в одному сценарії Python (в ідеалі).

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

Є близько 500 000 товарів, тому я трохи переживаю за виступи.

Це хороший шлях?


2
Вони хочуть, щоб ви теж зробили це із зав'язаними очима? Це моя проблема зараз ...
Капітан Гіпертекст

1
@ Тепер, як це пішло? Будь-яка порада, яку ви можете запропонувати зараз?
Едвін Еванс

4
@EdwinEvans в основному я залишився зі своєю першою ідеєю, але особливо через обмеження, які у мене були. Мій сценарій створює хеди md5 на основі ключових даних для всіх елементів. Потім я порівнюю з попередніми хешами. Якщо хеші різні, то він завантажує всі дані для елемента та оновлює все. Не впевнений, чи це найкращий спосіб, але він працює вночі, а виступи пристойні.
Neow

Відповіді:


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?
Fardin Behboudi

5

Синхронізація даних була б набагато кращою та швидшою, якщо це можна зробити на основі якогось дельта ідентифікатора чи прапора. В основному, ви повинні оновлювати цільові рядки даних db лише тоді, коли вони не синхронізовані з джерелом db.

У сервері SQL db ви можете скористатись контрольною функцією fn також для створення ідентифікатора на основі дельти.

Вам слід розробити завдання на базі SQL, щоб отримати виклик у певний час дня чи ночі, щоб звільнити цю логіку sql. Краще запускати його як нічну роботу SQL, коли використання db дуже низьке. Якщо дельта джерела та цільові записи db не збігаються, то витягніть лише ці записи. Але недоліком було б обчислювати контрольну суму рядків вихідних даних кожен раз, а потім порівнювати її з цільовими даними.

Якщо у таблиці вихідних db є стовпець типу "LastModifiedDate", ви можете пропустити підхід контрольної суми. Таким чином, ваше оцінювання буде виконано на колоні на основі дати та займе менше часу порівняно з підходом контрольної суми.


Дякую, але я не впевнений, що ваше рішення може спрацювати - дивіться мої зміни в частині "Проблеми".
Neow

Оскільки в базі даних джерела немає оновлених часових полів, нам залишається витягувати рядки кваліфікованих даних на основі контрольної суми або хеша.
Каран

Оскільки ваш джерело db2. Як ви маєте намір витягти дані з них? через якусь веб-службу чи API ..
Каран

Dsn був встановлений за допомогою драйвера odbc. Я можу підключатися та робити запити, використовуючи pyodbc для Python.
Neow

Добре, це добре, оскільки ви можете виконувати запити, використовуючи інструмент під назвою PyODBC у віддаленій БД. Можна зробити ще одну справу. Ви можете витягнути дані продукту прямо в тому ж форматі, що і в нову "Таблицю поетапних дій" у вашому цільовому БД без будь-яких перевірок чи перевірок. Таким чином, ви отримаєте живі дані за один кадр у вашому цільовому db під сценічними таблицями. Потім на другому кроці ви можете виконати операції контрольної суми та оновити цільові дані таблиці транзакцій. Це дозволить уникнути реального часу хешування або оцінки контрольної суми з вихідними даними db.
Каран

1

Використання хешу - хороша ідея. Оскільки безпека не є ціллю в цьому випадку, виберіть швидку хеш-функцію (md5 - це добре).

Якщо ви не плануєте розділити хеш-обчислення на декілька потоків / процесів, вам дійсно не потрібно зберігати поточне значення хешу в базі даних. Якщо ваш процес є єдиним сценарієм, ви просто будете мати в пам’яті поточний хеш і запишете його в базу даних як старий хеш після оновлення даних у новій базі даних.


-1

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


-1 (насправді не підкреслив, але;) для Windows лише пропозиція. давайте не будемо покладатися на якусь конкретну архітектуру при розробці програмного забезпечення, це просто означає, що лише деякі люди можуть використовувати ваші речі. Єдина константа - це зміни, тому краще не покладатися на будь-яку конкретну платформу в тій мірі, яка полегшує підтримку для себе та користувачів
pythonian29033

1
@manish kumar частина "вона знайде зміни у вашій базі даних" є найважчою!
Нарвалекс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.