Как объединить таблицы с первичными ключами autonumber?
Я полагаю, что все сталкиваются с этой проблемой время от времени: у вас есть две таблицы с первичными ключами autonumber, которые необходимо объединить. Есть много веских причин, почему первичные ключи autonumber используются в пользу ключей, созданных приложением, но слияние с другими таблицами должно быть одним из самых больших недостатков.
некоторые проблемы, которые возникают перекрывающиеся коды и синхронизации внешних ключей. Я хотел бы услышать ваш подход к решению этой проблемы. Я всегда натыкаюсь на проблемы, поэтому мне очень интересно, есть ли у кого-нибудь какое-то общее решение.
-- EDIT --
в ответ на ответы, предлагающие использовать GUID или другие нечисловые ключи, есть ситуации, когда заранее кажется, что лучше использовать ключи autonumber (и вы сожалеете об этом позже), или вы берете на себя чужой проект, или вы получаете некоторую устаревшую базу данных, с которой вам нужно работать. Так что я действительно ищу решение, где у тебя нет контроль над дизайном базы данных.
5 ответов
Хм, я с энтузиазмом отношусь к идее, что я только что вставил комментарий в ответ Алексюцнецова, поэтому я сделаю целый ответ об этом.
рассмотрим таблицы с именами table1 и table2, с id1 и id2 в качестве первичных ключей autonumber. Они будут объединены в table3 с id3 (первичный ключ без автономера).
почему бы и нет:
- удалите все ограничения внешнего ключа для table1 и table2
- для всех полей внешнего ключа, ссылающихся в таблице table1, выполнить
UPDATE table SET id1 = id1 * 2
, а для полей FK, ссылающихся на table2, выполнитеUPDATE table SET id2 = (id2) * 2 + 1
- заполнить table3, выполнив
INSERT INTO table3 SELECT id1 * 2 AS id3, ... FROM table1 UNION ALL SELECT id2 * 2 + 1 AS id3 FROM table2
- создать новый параметр таблица3
Он может даже работать с 3 или более таблицами, просто используя более высокий множитель.
решения:
используйте GUID в качестве первичных ключей вместо более простого поля идентификатора. Очень вероятно, чтобы избежать перекрытий, но GUID сложнее использовать и не играют хорошо с кластеризованными индексами.
сделайте первичный ключ многоколоночным ключом, второй столбец разрешает перекрывающиеся значения, идентифицируя источник объединенных данных. Портативный, лучше работает с кластеризованными индексами, но разработчики ненавидят многоколоночные ключи.
используйте натуральные ключи вместо псевдокеев.
выделите новые значения первичного ключа для одной из Объединенных таблиц и каскадируйте эти изменения в любые зависимые строки. Это изменяет операцию слияния в операцию ETL. Это единственное решение, которое вы можете использовать для устаревших данных, если вы не можете изменить дизайн базы данных.
Я не уверен, что есть решение одного размера для всех. Выберите один из них на основе ситуация.
один из стандартных подходов (если не на стандартный подход), где вы разрабатываете для такой возможности, использовать GUID для первичных ключей, а не целых чисел - слияние тогда относительно безболезненно, поскольку вы гарантированно не столкнетесь с перекрытием.
за исключением редизайна, tho', я думаю, вы застряли с необходимостью вставлять в таблицу, принять, что вы получите новые первичные ключи и убедитесь, что вы поддерживаете сопоставление от старого к новому ID-затем вставьте ссылка на данные с помощью FK remapped и т. д. так далее. Если у данных есть "бизнес-ключ", который останется уникальным после вставки, это сэкономит на необходимости отслеживать сопоставление.
Я уверен, что у вас есть только две такие таблицы ,вы можете просто иметь даже идентификаторы в одной таблице (0,2,4,6,...) и нечетные идентификаторы в другом (1,3,5,7,...)
предполагая, что у вас также есть естественный ключ в таблицах, которые нужно объединить, процесс не сложен. Естественный ключ используется для дедупликации и правильного переназначения любых ссылок. Вы можете перенумеровать значения суррогатных ключей в любое время - это одно из главных преимуществ использования суррогата в первую очередь.
поэтому я не вижу в этом проблемы с суррогатными ключами - при условии, что вы всегда применяете естественный ключ (на самом деле я предпочитаю термин "бизнес-ключ"). Если у вас нет бизнес-ключей для этих таблиц, ну, может быть, сейчас самое время перепроектировать, чтобы все необходимые ключи были правильно реализованы.