Как объединить таблицы с первичными ключами автонумерации? - PullRequest
7 голосов
/ 29 сентября 2010

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

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

- РЕДАКТИРОВАТЬ -

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

Ответы [ 5 ]

4 голосов
/ 29 сентября 2010

Решения включают в себя:

  • Используйте GUID в качестве первичных ключей вместо более простого поля идентификации. Скорее всего, избежать перекрытий, но GUID сложнее в использовании и не очень хорошо работает с кластерными индексами.

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

  • Используйте натуральные ключи вместо псевдокей.

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

Я не уверен, что есть универсальное решение для всех. Выберите один из них в зависимости от ситуации.

3 голосов
/ 30 сентября 2010

Хм, я в восторге от идеи, которую я только что добавил в комментарии к ответу Алекса Кузнецова, поэтому я сделаю полный ответ об этом.

Считайте таблицы именованными table1 иtable2, с id1 и id2 в качестве первичных ключей autonumber.Они будут объединены с таблицей 3 с идентификатором id3 (первичный ключ без номера).

Почему бы и нет:

  1. Удалить все ограничения внешнего ключа для таблиц1 и таблиц2
  2. Для всех полей внешнего ключа, относящихся к таблице 1, выполните UPDATE table SET id1 = id1 * 2, а для полей FK, относящихся к таблице 2, выполните UPDATE table SET id2 = (id2) * 2 + 1
  3. Заполнить таблицу 3, выполнив INSERT INTO table3 SELECT id1 * 2 AS id3, ... FROM table1 UNION ALL SELECT id2 * 2 + 1 AS id3 FROM table2
  4. Создать новыйограничения внешнего ключа для table3

Он может работать даже с 3 или более таблицами, просто используя более высокий множитель.

1 голос
/ 29 сентября 2010

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

Так что я не вижу в этом проблемы с суррогатными ключами - при условии, что вы всегда применяете естественный ключ (на самом деле я очень предпочитаю термин «бизнес-ключ»). Если у вас нет бизнес-ключей для этих таблиц, возможно, сейчас самое время изменить дизайн, чтобы ВСЕ необходимые ключи были правильно реализованы.

1 голос
/ 29 сентября 2010

Я уверен, у вас есть только две такие таблицы, вы можете просто иметь четные идентификаторы в одной таблице (0,2,4,6, ...) и нечетные идентификаторы в другой (1,3,5,7...)

1 голос
/ 29 сентября 2010

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

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

...