синхронизация данных из ненадежного источника данных в таблицу SQL - PullRequest
1 голос
/ 24 января 2012

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

Давайте рассмотрим пример только с 1 таблицей, чтобы было проще.

  • У меня ненадежный источник данных каталога продукции. Данные могут быть иногда недоступными или неполными или противоречивыми. (проблема может возникнуть из-за ошибки ручного ввода данных, сбоя ETL ...)

  • У меня есть живая копия в таблице Mysql, используемая действующей системой. Допустим, сайт.

Мне нужно реализовать механизм безопасности при обновлении таблицы mysql для «синхронизации» с исходным источником данных. Вот критерии безопасности и решение, которое я предлагаю:

  • избегать удаления записей, когда они временно исчезают из источника данных => использовать «удаленный» столбец булевой / даты или таблицу архива / истории.

  • проверка на несогласованные изменения => настроить правила для столбцов, такие как: никогда не должен изменяться, должен только увеличиваться,

  • проверка на предмет целостности => (стандартная проблема, нет смысла обсуждать подход)

  • возможность откатить последнюю синхронизацию => восстановить из таблицы истории? использовать версию inc / столбец даты?

То, что я ищу, - это лучшая практика и шаблон / инструмент для решения такой проблемы. Если нет, то вы не указываете на РЕШЕНИЕ, я был бы признателен за любые предложения по ключевым словам, которые позволили бы мне сузить область знаний, которую нужно изучить.

Ответы [ 2 ]

1 голос
/ 24 января 2012

У нас проблема с импортом данных от поставщиков веб-аналитики - у них те же проблемы, что и у вашего каталога. Вот что мы сделали:

  • Каждому импорту / синхронизации присваивается уникальный идентификатор (auto_increment int64)
  • Каждая таблица имеет таблицу истории, которая идентична исходной, но имеет дополнительный столбец «superseded_id», который получает идентификатор импорта для импорта, который изменил строку (удаление является изменением), и первичный ключ ( row_id, superseded_id)
  • Каждое ОБНОВЛЕНИЕ копирует строку в таблицу истории перед ее изменением
  • Каждый DELETE перемещает строку в таблицу истории

Это делает откат очень простым:

  • Узнайте import_id неверного импорта
  • REPLACE INTO main_table SELECT <everything but superseded_id> FROM history table WHERE superseded_id=<bad import id>
  • DELETE FROM history_table WHERE superseded_id>=<bad import id>

Для баз данных, где производительность является проблемой, мы делаем это во вторичной базе данных на другом сервере, а затем копируем основную таблицу, найденную для исправления, в рабочую базу данных в новую таблицу main_table_$id с $ id является самым высоким идентификатором импорта и имеет main_table тривиальное представление SELECT * FROM main_table_$someid. Теперь, переопределив представление на SELECT * FROM main_table_$newid, мы можем атомно перебрать таблицу.

0 голосов
/ 24 января 2012

Я не знаю ни одного решения для всего этого - вероятно, потому что каждый проект настолько отличается. Однако вот две техники, которые я использовал в прошлом:

Внедрить концепцию версии и достоверности в вашу модель данных

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

Например, вместо таблицы продуктов следующим образом

PRODUCTS
Product_ID primary key
Price
Description
AvailableFlag

В этой модели, если вы хотите удалить продукт, вы выполняете "delete from product where product_id = ..."; изменяющая цена будет "update products set price = 1 where product_id = ...."

С версионной моделью у вас есть:

PRODUCTS
product_ID primary key
valid_from datetime
valid_until datetime
deleted_flag
Price
Description
AvailableFlag

В этой модели для удаления товара требуется update products set valid_until = getdate() where product_id = xxx and valid_until is null, а затем вставьте новую строку со значением «dele_flag = true».

Изменение цены работает так же.

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

Использовать механизм, подобный регистру, для кумулятивных значений

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

Например, вместо столбца amount_in_stock в вашей таблице продуктов, есть таблица "product_stock_transaction":

product_stock_transactions 
product_id FK        transaction_date     transaction_quantity transaction_source
1                    1 Jan 2012             100                 product_feed
1                    2 Jan 2012              -3                 stock_adjust_feed
1                    3 Jan 2012              10                 product_feed

2 января количество на складе было 97; 3 января 107.

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

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

Трудно заранее спланировать проблемы с производительностью - я видел, как "история" и "бухгалтерская книга" работают с большими объемами данных. Однако, как говорит Евгений в своем комментарии ниже, если вы попадете в слишком большую бухгалтерскую книгу, может потребоваться очистить таблицу бухгалтерской книги, суммируя текущие уровни и удаляя (или архивируя) старые записи.

...