Когда не следует использовать суррогатные первичные ключи? - PullRequest
9 голосов
/ 11 ноября 2009

У меня есть несколько таблиц базы данных, которые содержат только один столбец и очень мало строк, часто просто идентификатор чего-то определенного в другой системе. Затем на эти таблицы ссылаются внешние ключи из других таблиц. Например, одна таблица содержит коды стран (SE, DK, US и т. Д.). Все значения всегда являются уникальными естественными ключами и используются в качестве первичных ключей в других (устаревших) системах.

Кажется, действительно нет необходимости вводить новый суррогатный ключ в эти таблицы, или?

В целом, в каких исключительных случаях не следует использовать суррогатные ключи?

Ответы [ 6 ]

22 голосов
/ 11 ноября 2009

Я бы сказал, что должны быть соблюдены следующие критерии:

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

  • Ваш естественный ключ должен быть таким же маленьким, как INT, например, не намного больше, чем 4 байта (не используйте VARCHAR (50) для вашего ПК, и особенно не для вашего ключа кластеризации в SQL Server!)

  • Ваш естественный ключ должен быть стабильным, например никогда не меняются (хорошо, с кодами стран ИСО, это почти что дано - за исключением случаев, когда такие страны, как Югославия или СССР, или другие, такие как две Германии объединяются - но это достаточно редко)

Если эти условия соблюдены, вы можете считать естественный ключ своим PK - но это должно быть 2% -ное исключение во всех ваших таблицах - не норма.

3 голосов
/ 11 ноября 2009

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

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

2 голосов
/ 11 ноября 2009

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

Из этой статьи :

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

2 голосов
/ 11 ноября 2009

Натуральные ключи (коды стран в вашем случае) лучше, потому что

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

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

Итак, если в вашей БД логика не меняется в течение многих лет, используйте естественные ключи.

0 голосов
/ 11 ноября 2009

Использование естественных ключей в целях идентификации - хорошая идея, когда естественным ключам действительно можно доверять. См. Ответ Marc_S для некоторых случаев, когда естественным ключам нельзя доверять. Не беспокойтесь об эффективности. Даже что-то длинное, например, VIN (идентификационный номер транспортного средства) не сильно затянет вашу базу данных. Если вы считаете, что это произойдет, проведите несколько тестов, понимая, что эффективность не масштабируется линейно.

Основная причина объявления первичного ключа состоит в том, чтобы предотвратить выпадение таблицы из первой нормальной формы и, таким образом, больше не представлять отношение. Использование автоинкрементного суррогатного ключа может привести к двум строкам с разными полями id, но в остальном идентичные. Это принесет вам некоторые проблемы, связанные с данными, которые не в первой нормальной форме. И пользователи не смогут помочь, потому что они не могут видеть поле id.

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

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

0 голосов
/ 11 ноября 2009

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

...