2012-09-17 3 views
0

(tldr, я думаю, что периодические обновления заставляет таблицу использовать естественный ключ И поэтому я должен перенести свою схему базы данных.).Как создать схему для обработки периодических объемных вставок/обновлений?

У меня есть базы данных производства с таблицей как планет, которые хотя у него есть хорошие потенциальные естественные ключи (например, имена планет, которые никогда не изменяются), в качестве первичного ключа используется типичное добавочное целое число. В таблице планет имеется столбец с саморегуляцией или два, например * parent_planet_id *.

Теперь я создаю офлайн-облачных работников, которые воссоздают подмножества записей планет каждую неделю, и их необходимо интегрировать с основным сервером. Мой план:

  • Экземпляр работника имеет мини-версию базы данных (такую ​​же схему, но нет планет записи)
  • Раз в неделю, рабочий разжигает, делает всю свою обработку, создает его 100 000 или так что записи планет и экспорт данных. (Я не думаю, что формат экспорта имеет значение для этой конкретной проблемы: может быть mysqldump, yaml и т. Д.)
  • Затем производственный сервер импортирует записи: некоторые из них являются новыми, большинство из них - обновлениями.

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

Я думал об экспорте без столбца id, но потом понял, что столбцы с самосогласованием предотвращают это.

Я вижу два возможных решения:

  • перепроектировать схему, чтобы использовать естественный ключ для таблицы планет. Это было бы болью.
  • Используйте UUID вместо инкрементирующего целого для ключа. Было бы легче, я думаю, переехать. Идентификатор будет уникальным, и новые строки могут быть безопасно импортированы. Это также позволяет избежать проблем в зависимости от естественных данных в ключах.
+0

Вам понадобится обновить планету, которая уже существует в базе данных «master», или вы всегда будете ВСТАВИТЬ? –

+0

Большинство операций - это обновления ... – Dogweather

ответ

1

Измените Planets использовать технику альтернативной-иерархии, как nested sets, закрытия таблицы или пути перечисления и чем экспорт. Это нарушит ID-зависимость.

Или, если вам все еще не нравится эта идея, рассмотрите возможность экспорта и импорта в качестве проблемы с ETL.

  • Изменить запись при экспорте включить PlanetName, ParentPlanetName
  • Импорт всех планет (PlanetNames) первый
  • Затем импортировать иерархию (ParentPlanetName)

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

0

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

Проще (я думаю), и все же немного «счастливое инженерное» решение заключалось бы в изменении импортирующих ключей. Вы можете сделать это, например, так: 1. закройте таблицу планет в основной системе (поэтому во время импорта не появится новый ключ), 2. создайте таблицу поиска с двумя столбцами, идентификатором и именем PLANET на основе таблицы планет в основной системе , 3. получить максимальное значение ключа из этой таблицы, 4. увеличивать каждый импортированный ключ (идентифицировать и ссылаться на отношение родительско-детской планеты), добавляя значение MAX, полученное в шаге # 3, 5. изменить таблицу основной планеты и измените текущее значение автоматического приращения для фактического значения MAX + 1. 6. Теперь перейдите по таблице (курсор в процедуре), проверяя, если для текущего названия планеты у вас есть другой ключ в вашем поиске, если да сначала удалите запись из таблицы с ключом поиска (старый) и обновить значение ключа в текущей проверенной строке для старого id (t шляпа была обновлена), 7. разблокируйте стол.

0

Большинство операций обновления

Так что вам нужно "реальный" слияние. Другими словами, вам нужно будет определить правильный заказ, в котором вы можете ВСТАВИТЬ/ОБНОВИТЬ данные, поэтому в процессе не будут нарушены FK.

Я не уверен, что означает parent_planet_id, но при условии, что это означает «орбиты», а слово «планета» растянуто так же, как и луны, представьте, что в вашей базе данных есть только Фобос, а Марс и Деймос необходимо импортировать , Это может быть сделано только в определенном порядке:

  1. INSERT Mars.
  2. INSERT Deimos, установите его parent_planet_id, чтобы он указывал на Марс.
  3. ОБНОВЛЕНИЕ Фобос parent_planet_id поэтому он указывает на Марс.

В то время как вы могли обмениваться шагами (2) и (3), вы не могли сделать либо до шага (1).

Вам понадобится рекурсивный спуск, чтобы определить правильный порядок, а затем сравнить натуральные ключи , чтобы узнать, что нужно ОБНОВИТЬ и что ВСТАВЛЕНО. К сожалению, MySQL не поддерживает рекурсивные запросы, поэтому вам нужно будет сделать это вручную.

Я не совсем понимаю, как помогают суррогатные ключи в этом процессе - если что-нибудь, они добавляют еще один уровень косвенности, который вам в конечном итоге придется примирить.


Который, в отличие от суррогатов, имеет смысл в различных базах данных. Вы не можете просто сравнивать автоматически увеличивающиеся целые числа, потому что одно и то же целочисленное значение может идентифицировать разные планеты в разных базах данных - у вас будут ложные UPDATE. GUID, с другой стороны, никогда не будут совпадать, даже если строки описывают одну и ту же планету - у вас будут ложные INSERT.

Смежные вопросы