Внешние ключи - ссылка, использующая суррогатный или натуральный ключ?

14

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

Основная причина для этого заключается в том, что у меня есть устаревшее приложение, которое использует FK с естественными ключами, но разработчики сильно настаивают на переходе к OR / M (в нашем случае NHibernate), и форк уже произвел некоторые Нарушая изменения, я собираюсь либо вернуть их на ход, используя естественный ключ, либо переместить старое приложение, чтобы использовать суррогатные ключи для FK. Моя интуиция говорит, чтобы восстановить оригинальный FK, но я честно не уверен, действительно ли это правильный путь.

В большинстве наших таблиц уже определены как суррогатный, так и естественный ключ (хотя уникальное ограничение и PK), поэтому в этом случае нам не нужно добавлять дополнительные столбцы. Мы используем SQL Server 2008, но я надеюсь, что это достаточно универсально для любой БД.

Крис Дж
источник

Ответы:

15

Ни SQL, ни реляционная модель не нарушаются внешними ключами, которые ссылаются на естественный ключ. Фактически, ссылки на естественные ключи часто значительно улучшают производительность. Вы будете удивлены, как часто нужная вам информация полностью содержится в естественном ключе; ссылка на этот ключ меняет объединение на более широкую таблицу (и, следовательно, уменьшает количество строк, которые можно сохранить на одной странице).

По определению необходимая информация всегда полностью содержится в естественном ключе каждой таблицы «поиска». (Термин таблица поиска является неформальным. В реляционной модели все таблицы являются просто таблицами. Таблица почтовых индексов США может иметь строки, которые выглядят следующим образом: {AK, Аляска}, {AL, Алабама}, {AZ, Аризона} и т. д. Большинство людей называют это справочной таблицей.)

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

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

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

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

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

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

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

Другие соответствующие ответы: в схеме базы данных сбивает с толку

Майк Шеррилл 'Cat Recall'
источник
5

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

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

Как избежать соединения с использованием естественного ключа. Да, это может ускорить операторы select, которые не нуждаются в объединениях, но это приведет к тому, что места, где вам все еще нужны объединения, будут медленнее, поскольку соединения int, как правило, быстрее. Это также, вероятно, замедлит вставки и удаления и вызовет проблемы с производительностью обновлений при смене ключа. Сложные запросы (которые все равно медленнее) будут еще медленнее. Таким образом, простые запросы выполняются быстрее, но отчеты и сложные запросы и многие действия с базой данных могут выполняться медленнее. Это балансирование, которое может измениться так или иначе, в зависимости от того, как запрашивается ваша база данных.

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

HLGEM
источник
1
«… Естественные ключи часто подвержены изменениям…» - значит, они не очень хорошие ключи! Если атрибут часто меняется, не используйте его в качестве ключа (конечно, для различных определений «часто»). Фабиан Паскаль утверждал, что существует четыре критерия выбора ключа: фамильярность, неприводимость, стабильность и простота. Иногда вы обмениваете их на простоту суррогатного ключа. Как сказал HLGEM: «Так что нет универсального ответа на все вопросы».
Гринстоун Уолкер
1
@ GreenstoneWalker, я бы согласился, что вы не должны использовать его в качестве ключа, но часто у вас нет ключа, который соответствует всем четырем критериям, и вы должны идти с тем, что является уникальным. И когда уникальность является противоположным ключом, тогда проблема может быть еще большей с точки зрения производительности, когда у вас должны быть объединения.
HLGEM
-4

Если вы не знаете ответ, иди с суррогатом. Вот почему - если сделаны предположения о бизнес-правилах, и эти предположения ложны или правила меняются, ваши данные являются мусором. Вот пример:

Персона, Роль, ПерсонаРоль

текущее бизнес-правило гласит, что человек имеет одну роль. Вы создаете таблицу, которая связывает Person и Role, где PersonRole (PersonName, PersonBirthDate, PersonMotherMaidenName, ..., RoleCode)

Теперь вы настоящий пурист, когда речь заходит о Natural Keys! А если серьезно, что если организация решит, что человек теперь может выполнять несколько ролей? Каковы последующие эффекты поддержки изменения потребностей бизнеса?

philn5d
источник
2
И у вас нет этих проблем с суррогатными ключами? Пожалуйста, покажите нам, как.
Colin 't Hart
4
Приведенный пример, похоже, не демонстрирует ничего, имеющего отношение к обсуждению.
Мустаччо