Суррогатные против натуральных / деловых ключей [закрыто]

174

Здесь мы идем снова, старый аргумент все еще возникает ...

Должны ли мы иметь бизнес-ключ в качестве первичного ключа или лучше иметь суррогатный идентификатор (т. Е. Идентификатор SQL Server) с уникальным ограничением на поле бизнес-ключа?

Пожалуйста, предоставьте примеры или доказательства в поддержку вашей теории.

Манрико Корацци
источник
24
@Joachim Sauer: Аргумент о том, является ли вещь субъективным, сам по себе может быть субъективным, без какого-либо отношения к объективности или субъективности рассматриваемой вещи. Если вы не готовы сформулировать точные объективные критерии, которые делают что-то объективным. Есть вещи, называемые «открытыми понятиями», например, сколько волос нужно, чтобы сделать бороду. Можно объективно сказать, что у человека без волос на подбородке нет бороды, а у человека с 5000 волосками на дюйм - борода, но где-то посередине субъективное суждение необходимо для объективного определения.
ErikE
@Manrico: вы просто должны спросить себя: если я не использую суррогатный ключ, мой первичный ключ все еще будет неизменным? Если ответ «нет», вам следует серьезно подумать об использовании суррогатного ключа. Кроме того, если первичный ключ составлен хотя бы частично из пользовательских данных, вам следует рассмотреть возможность использования суррогатного ключа. Зачем? Из-за опасности аномалий данных.
code4life
@TylerRick Но это не совсем хороший вопрос. Он требует решения, которое в целом применимо ко всем ситуациям, когда явно нет таковых, что доказано «религиозной войной», о которой спрашивающий прекрасно знает (цитата: «Вот, пожалуйста, старый аргумент все еще возникает. .. "). Вместо того, чтобы задаваться вопросом, изменился ли мир, и, наконец, была предоставлена ​​убедительная причина, чтобы всегда выбирать одну сторону, лучше продолжать задавать этот вопрос снова и снова для каждой конкретной ситуации и отправлять сообщения в SO, если вы не уверены , Это просто вызывает догматизм.
MarioDS

Ответы:

97

Обе. Возьми свой торт и съешь его.

Помните, что в первичном ключе нет ничего особенного, кроме того, что он помечен как таковой. Это не более чем ограничение NOT NULL UNIQUE, и таблица может иметь более одного.

Если вы используете суррогатный ключ, вы все равно хотите, чтобы бизнес-ключ гарантировал уникальность в соответствии с бизнес-правилами.

Тед
источник
7
Если у вас есть несколько ключей-кандидатов (полей или наборов полей одинакового размера, которые НЕ УНИКАЛЬНЫ), то вы, вероятно, нарушаете нормальную форму Бойса-Кодда. BCNF выходит за рамки 3NF, поэтому об этом беспокоятся не многие. Однако существуют ситуации, когда пребывание в BCNF очень полезно.
Алан
2
Согласовано. Реальный вопрос должен быть следующим: должен ли я добавить уникальный суррогатный ключ в мои таблицы? Совершенно другой вопрос - что использовать для логического первичного ключа. Они оба по сути просто ненулевые ограничения уникального индекса.
dkretz
1
«Каждая проблема решается с помощью другого уровня косвенности» ... Суррогатные ключи - это просто еще один уровень косвенности
Стив Шнепп
5
Я нахожу странным, что многие комментарии, кажется, утверждают, что нельзя установить отношения без суррогатного ключа. Во многих случаях суррогатный ключ является излишним. Зачем добавлять что-то, что не приносит никакой пользы, но добавляет технический долг (а в некоторых случаях приводит к тому, что в противном случае уникальный результат внезапно становится неуникальным).
Уил Мур III
2
Это более чем НЕ УКАЗАНО УНИКАЛЬНОЕ ограничение. Первичный ключ используется в качестве кластерного индекса, который определяет физический порядок ваших данных. В целом, Integer легко сбалансировать, поскольку он последовательно увеличивается, и ваши данные добавляются в EOF на диске. Если вы используете менее последовательные данные, такие как текст или GUID (UUID), будет намного больше дискового ввода-вывода и усилий для балансировки индекса, я думаю, что это большая разница
Jin
124

Несколько причин использовать суррогатные ключи:

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

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

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

Джей Шепард
источник
2
Теперь, прочитав много о суррогатных ключах и естественных ключах, я думаю, что лучше использовать суррогатные ключи. Но в моей базе данных естественные ключи (NVARCHAR (20)) должны быть уникальными. Я не понимаю, как мне добиться большей скорости, если мне нужно проверять все данные в этом столбце, чтобы не повторять любое значение (используя ограничение NOT NULL UNIQUE) для каждой вставки.
VansFannel
70

Похоже, что никто еще ничего не сказал в поддержку несуррогатных (я не решаюсь сказать «естественных») ключей. Так что здесь идет ...

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

select sum(t.hours)
from timesheets t
where t.dept_code = 'HR'
and t.status = 'VALID'
and t.project_code = 'MYPROJECT'
and t.task = 'BUILD';

против:

select sum(t.hours)
from timesheets t
     join departents d on d.dept_id = t.dept_id
     join timesheet_statuses s on s.status_id = t.status_id
     join projects p on p.project_id = t.project_id
     join tasks k on k.task_id = t.task_id
where d.dept_code = 'HR'
and s.status = 'VALID'
and p.project_code = 'MYPROJECT'
and k.task_code = 'BUILD';

Разве кто-нибудь всерьез считает, что следующая идея - хорошая идея?

select sum(t.hours)
from timesheets t
where t.dept_id = 34394
and t.status_id = 89    
and t.project_id = 1253
and t.task_id = 77;

«Но, - скажет кто-то, - что произойдет, когда код для MYPROJECT, VALID или HR изменится?» На что мой ответ был бы: «почему бы вам нужно изменить его?» Это не «естественные» ключи в том смысле, что какой-то внешний орган собирается издать закон о том, что впредь «ДЕЙСТВИТЕЛЬНО» следует перекодировать как «ХОРОШО». Только небольшой процент «естественных» ключей действительно попадает в эту категорию - обычными примерами являются SSN и Zip-код. Я бы определенно использовал бессмысленный цифровой ключ для таблиц, таких как Person, Address - но не для всего , что, по некоторым причинам, большинство людей здесь защищают.

Смотрите также: мой ответ на другой вопрос

Тони Эндрюс
источник
14
-1 Естественные ключи в качестве первичного ключа имеют проблему, заключающуюся в том, что для каждой дочерней таблицы необходимо добавить ключ родителя, который может состоять из нескольких полей (вместо одного, как в случае суррогатного ключа), а также дочернего ключа. ключ. Итак, представьте себе следующее, где начиная с TABLEA отношение равно 1-0 .. *: TABLEA PK: ID_A TABLEB PK: ID_A ID_B TABLEC PK: ID_A ID_B ID_C TABLED PK: ID_A ID_B ID_C ID_D. Видишь проблему? Родительский ключ распространяется в дочерних таблицах. Что произойдет, если изменится первичный ключ TABLEA? Теперь вам также придется провести рефакторинг всех дочерних таблиц PK.
Альфредо Осорио
9
@ Альфредо: да, конечно, есть компромисс. Однако за 20 с лишним лет опыта я редко видел определение изменения ПК в таблице. Если бы это происходило на регулярной основе, я бы, вероятно, тоже избегал использования натуральных ключей. На самом деле, в очень редких случаях, когда это происходит, я готов принять удар от продолжительного воздействия.
Тони Эндрюс
10
Я не согласен. Часто тот случай, когда какой-то внешний орган (клиент) устанавливает, что естественный ключ необходимо редактировать и, следовательно, распространять по всей системе. Я вижу, что это происходит регулярно. Единственный способ убедиться, что ключ никогда не понадобится менять, - это когда он по определению не имеет смысла. Кроме того, современные базы данных обрабатывают внутренние объединения чрезвычайно эффективно, поэтому потенциально большие выгоды от использования суррогатов, как правило, перевешивают преимущество, заключающееся в том, что не нужно выполнять столько внутренних объединений.
TTT
8
@TTT: Тогда дизайн был слабым для начала. Опять же, именно здесь мужчины отделяются от мальчиков: делают правильный выбор, когда использовать естественный ключ, а когда использовать суррогат. Вы решаете это на основе таблицы, а не как общая догма.
DanMan
7
У меня также более 20 лет опыта, и я придерживаюсь вашего мнения. Однажды я создал хранилище данных Oracle с суррогатными ключами, и обслуживание данных было адом. Вы просто никогда не сможете напрямую получить доступ к своим данным. вам всегда нужно писать запросы для всего, и это делает суррогатные ключи просто ужасными в обращении.
Полиция SQL
31

Суррогатный ключ НИКОГДА не будет иметь причины для изменения. Я не могу сказать то же самое о естественных ключах. Фамилии, электронные письма, номера ISBN - все они могут измениться за один день.

Римантас
источник
31

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

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

Think Companies: вы - счастливая компания Merkin, которая ведет дела с другими компаниями в Merkia. Вы достаточно умны, чтобы не использовать название компании в качестве первичного ключа, поэтому вы используете уникальный идентификатор компании правительства Merkia из 10 буквенно-цифровых символов. Затем Merkia меняет идентификационные данные компании, потому что они думали, что это будет хорошей идеей. Это нормально, вы используете функцию каскадных обновлений вашего db-движка, для изменения, которое не должно вас привлекать. Позже ваш бизнес расширяется, и теперь вы работаете с компанией во Фридонии. Идентификатор компании Freedonian - до 16 символов. Вам необходимо увеличить первичный ключ идентификатора компании (также поля внешнего ключа в Заказах, Выпусках, MoneyTransfers и т. Д.), Добавив поле Страна в первичном ключе (также во внешних ключах). Ой! Гражданская война во Фридонии разделены на три страны. Название страны вашего сотрудника должно быть изменено на новое; каскадные обновления на помощь. Кстати, каков твой первичный ключ? (Страна, CompanyID) или (CompanyID, Страна)? Последний помогает объединениям, первый избегает другого индекса (или, возможно, многих, если вы хотите, чтобы ваши Заказы также группировались по странам).

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

tzot
источник
Вы выиграли все интернет с самым крутым именем пользователя!
Iain Holder
1
Это в значительной степени то, что отрицательный голос: «Я не согласен с этим».
jcollum
5
Всплывающая подсказка со стрелкой вниз гласит: «Этот ответ бесполезен», а не «Я не согласен с этим». Возможно, в этом конкретном ответе значения близки, но в целом они не одинаковы.
tzot
1
Если кто-то думает, что ваш ответ неправильный, то он (она) также будет думать, что он ведет спрашивающего в неправильном направлении (противоположном правильному направлению), и поэтому будет считать ваш ответ еще хуже, чем «бесполезный», оправдывая в своем (/ ее) уме отрицательный голос.
Эрвин Смут
1
Да, суррогатные ключи - это болезнь. Один просачивается в дикую природу, и вы используете его в качестве пки, так что теперь вам нужен собственный суррогатный ключ. Тогда ваш ключ просачивается в дикую природу (скажем, через URL), и болезнь распространяется.
Самуэль Дэниелсон
25

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

Вот мои причины:

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

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

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

  4. В цепочке отношений один ко многим цепочки логических ключей. Так, например, в организациях есть много счетов, а в счетах много счетов. Таким образом, логический ключ организации - OrgName. Логический ключ Учетных записей - OrgName, AccountID. Логическим ключом Invoice является OrgName, AccountID, InvoiceNumber.

    Когда используются суррогатные ключи, цепочки ключей усекаются, имея только внешний ключ для непосредственного родителя. Например, таблица Invoice не имеет столбца OrgName. Он имеет только столбец для AccountID. Если вы хотите искать счета для определенной организации, вам нужно будет присоединиться к таблицам Организация, Учетная запись и Счет. Если вы используете логические ключи, то вы можете запросить таблицу организации напрямую.

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

  6. У меня есть три разные базы данных книг. Ни один из них не показывает использование суррогатных ключей.

кругозор
источник
7
Я ненавижу суррогатные ключи, кроме случаев, когда они необходимы. Они необходимы, когда предприятие использует естественный ключ, который подвержен множеству ошибок, и не желает мириться с базой данных, на которую влияют эти ошибки.
Уолтер Митти
26
-1: я написал и поддерживал десятки приложений. Среди проблем, связанных с данными, были те, которые использовали естественные ключи.
Сокол
6
Некоторые из ваших предположений предполагают, что суррогатный ключ должен быть PK или столбцом кластера - это не так. Ваши пункты 1 и 5 игнорируют тот факт, что целые числа составляют 4 байта, а естественные ключи - почти всегда много, намного больше байтов. И каждый некластеризованный индекс должен повторять байты тех естественных ключей, которые есть в кластеризованном индексе, поэтому таблицы и индексы в вашей базе данных естественных ключей будут иметь намного, намного меньше строк на страницу, что приведет к гораздо худшей производительности чтения. , что делает запросы медленнее , а не быстрее.
ErikE
3
Другая причина против естественных ключей (примеры: атомные номера, VIN и т. Д.) Может изменить бизнес-логику, увеличивая тип данных. Например: до: отслеживание зарядов атомов, после: отслеживание зарядов атомов и соединений. До: Отслеживание автотранспорта на грузоподъемность. После: добавление самолетов, лодок, велосипедов и людей для увеличения грузоподъемности.
forforf
3
Я предполагаю, что у вас нет таблиц, в которых первичный ключ составлен хотя бы частично из 1) любого атрибута, который может и будет изменяться) или 2) из ​​пользовательского ввода (например, динамически генерируемые списки поиска). Если вы не можете гарантировать неизменность ключа, вам придется обновить все эти взаимосвязи сущностей с помощью кода или сценариев ручного исправления. Если вам никогда не приходилось это делать ... Я думаю, ваша база данных является суррогатной без ключа и ... необычной.
code4life
18

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

Поскольку многие люди представляют суррогатные ключи как почти идеальное решение, а естественные ключи - как чуму, я остановлюсь на аргументах другой точки зрения:

Недостатки суррогатных ключей

Суррогатными ключами являются:

  1. Источник проблем с производительностью:
    • Они обычно реализуются с использованием автоматически увеличиваемых столбцов, что означает:
      • Обход в базу данных каждый раз, когда вы хотите получить новый Id (я знаю, что это можно улучшить с помощью алгоритмов кэширования или [seq] hilo, но все же эти методы имеют свои недостатки).
      • Если однажды вам понадобится переместить ваши данные из одной схемы в другую (по крайней мере, в моей компании это происходит довольно регулярно), то у вас могут возникнуть проблемы с коллизиями Id. И да, я знаю, что вы можете использовать UUID, но для того, чтобы это длилось, требуется 32 шестнадцатеричных числа! (Если вы заботитесь о размере базы данных, это может быть проблемой).
      • Если вы используете одну последовательность для всех ваших суррогатных ключей, то - наверняка - вы получите конфликт в вашей базе данных.
  2. Ошибка склонна. Последовательность имеет ограничение max_value, поэтому, как разработчик, вы должны обратить внимание на следующие моменты:
    • Вы должны циклически повторять свою последовательность (когда достигается максимальное значение, оно возвращается к 1,2, ...).
    • Если вы используете последовательность как порядок (со временем) ваших данных, то вы должны обработать случай цикличности (столбец с Id 1 может быть новее, чем строка с Id max-value - 1).
    • Убедитесь, что ваш код (и даже ваши клиентские интерфейсы, которые не должны происходить так, как это должно было бы быть внутренним идентификатором), поддерживает целые числа 32b / 64b, которые вы использовали для хранения значений последовательности.
  3. Они не гарантируют не дублированные данные. Вы всегда можете иметь 2 строки с одинаковыми значениями столбца, но с другим сгенерированным значением. Для меня это проблема суррогатных ключей от проектной базы данных точки зрения.
  4. Больше в Википедии ...

Мифы о природных ключах

  1. Составные ключи менее неэффективны, чем суррогатные ключи. Нет! Это зависит от используемого движка базы данных:
  2. Естественные ключи не существуют в реальной жизни. Извините, но они существуют! Например, в авиационной промышленности следующий кортеж всегда будет уникальным в отношении заданного регулярного рейса (авиакомпания, вылет даты, номер рейса, оперативный суффикс). В более общем случае, когда набор бизнес-данных гарантированно является уникальным по данному стандарту тогда этот набор данных является [хорошим] кандидатом в естественный ключ.
  3. Естественные ключи «загрязняют схему» дочерних таблиц. Для меня это больше чувство, чем настоящая проблема. Наличие первичного ключа из 4 столбцов по 2 байта каждый может быть более эффективным, чем один столбец из 11 байтов. Кроме того, 4 столбца можно использовать для непосредственного запроса к дочерней таблице (используя 4 столбца в предложении where) без присоединения к родительской таблице.

Вывод

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

Надеюсь, что это помогло кому-то!

mwnsiri
источник
3
Что происходит, когда дата вылета запланированного рейса перенесена? Нужно ли отслеживать все связанные объекты и удалять ключи, или вы действительно обновляете все ключи в связанных объектах? Или вы имеете дело с простой единственной таблицей (возможно, даже не 3NF)?
code4life
Отличная точка @ code4life
Forcewill
@ code4life: Вот где включается операционный суффикс. Чтобы сохранить тот же номер flightNumber, чтобы избежать путаницы с клиентами, мы добавляем только суффикс (например, «D»).
Mwnsiri
«Вы всегда можете иметь 2 строки с одинаковыми значениями столбцов, но с другим сгенерированным значением», поэтому просто наложите уникальное или составное уникальное ограничение на ваши столбцы.
7
15

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

РЕДАКТИРОВАТЬ: Я пытался найти ссылку на него в Интернете, но я не мог. Однако в «Паттернах корпоративной архитектуры» [Фаулер] есть хорошее объяснение того, почему вы не должны использовать ничего, кроме ключа, не имеющего никакого значения, кроме как быть ключом. Это сводится к тому, что у него должна быть одна работа и только одна работа.

Iain Holder
источник
22
Мартин Фаулер может быть многим, но он не является авторитетом в области проектирования баз данных.
Тони Эндрюс
Я думаю, что вы должны представить некоторые аргументы, прежде чем прийти к выводу.
Арне Эвертссон
4
@ArneEvertsoon Причина здесь. «Это сводится к тому, что у него должна быть одна работа и только одна работа». Единственная ответственность.
Iain Holder
10

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

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

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

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

Дерек Лоулесс
источник
6

На мой взгляд, лучше использовать суррогатный ключ, поскольку вероятность его изменения практически отсутствует. Почти все, что я могу придумать, которое вы можете использовать в качестве естественного ключа, может измениться (отказ от ответственности: не всегда верно, но обычно).

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

Марк Эмблинг
источник
1
К сожалению, у автомобилей есть естественный ключ, который не меняется: VIN (по крайней мере, в Америке ...)
jcollum
@jcollum Да, хорошо, это справедливо. Мое мнение все еще остается верным, мой пример не обязательно был так хорош, как мог бы быть.
Марк Эмблинг
2
Список языков был бы примером для естественного ключа, когда вы основываете его на кодах ISO. Поэтому, если вы хотите загрузить контент из таблицы на определенном языке, вам не нужно объединяться в languagesтаблицу, поскольку код языка (ID) уже находится в textsтаблице.
DanMan
@ DanMan Я должен согласиться с вами там. Всегда будут примеры, которые лучше работают с естественным ключом. Правила или общие подходы никогда не бывают абсолютными, и это один из примеров, на который я бы на 100% согласился с вашим подходом :-)
Марк Эмблинг
5

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

Затем при необходимости составьте свои бизнес-ключи как уникальные ограничения или индексы. Это сохранит целостность данных.

Бизнес-логика / естественные ключи могут измениться, но физический ключ таблицы НИКОГДА не должен изменяться.

user7658
источник
4

Я считаю, что в сценарии с хранилищем данных лучше следовать суррогатному ключевому пути. Две причины:

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

Суррогатные ключи могут быть полезны, когда деловая информация может измениться или быть идентичной. В конце концов, названия компаний не обязательно должны быть уникальными по всей стране. Предположим, вы имеете дело с двумя компаниями под названием Smith Electronics, один в Канзасе и один в Мичигане. Вы можете различить их по адресу, но это изменится. Даже государство может измениться; Что делать, если Smith Electronics из Канзас-Сити, штат Канзас, переходит через реку в Канзас-Сити, штат Миссури? Не существует очевидного способа отличить эти предприятия от естественной ключевой информации, поэтому суррогатный ключ очень полезен.

Думайте о суррогатном ключе как о номере ISBN. Обычно вы определяете книгу по названию и автору. Тем не менее, у меня есть две книги под названием «Перл-Харбор» от HP Willmott, и это определенно разные книги, а не просто разные издания. В таком случае я мог бы сослаться на внешний вид книг или более ранних по сравнению с более поздними, но я также должен использовать ISBN.

Дэвид Торнли
источник
1
Я думаю, что я должен не согласиться с вашим примером здесь. Номер ISBN является атрибутом книги. Суррогатный ключ не зависит от остальных данных строки, поэтому эта позиция будет рекомендовать использование отдельного суррогатного ключа для таблицы книг, даже если ISBN уже уникально идентифицирует каждую книгу.
Кристофер Кашелл
Альтернативно, думайте о ISBN как о суррогатном ключе. Это идентификатор без значения, просто код, который применяется к определенной книге. Если вы создаете таблицу книг, ISBN также может быть первичным ключом (при условии, что у вас всегда есть одна книга на строку).
Дэвид Торнли
@Christopher Cashell - наткнулся на этот пост год назад, но я подумал добавить что-нибудь. ISBN не гарантированно являются уникальными и могут иметь дубликаты. У меня есть друг, который работал в библиотеке в течение нескольких лет, и они часто сталкивались с книгами с дубликатами ISBN. Проблема в том, что уникальность ISBN лежит на издателе, а не на одном органе, который гарантирует, что все числа для всех публикаций являются уникальными, и эти издатели не всегда были вместе.
Томас,
2
Наткнулся на этот пост год назад и хотел упомянуть, что ISBN на самом деле являются естественными ключами. В отличие от суррогатного ключа в самом значении ключа есть смысл. Например, часть ключа идентифицирует издателя. Кроме того, как я уже упоминал выше, они не гарантируют уникальности. Они должны быть уникальными, но эта уникальность исходит от издателей, и они не всегда были идеальными.
Томас,
Технически корпорации не могут перемещаться между государствами; то, что происходит, - то, что новая корпорация создана в новом государстве, и активы переданы. Это работает для информации базы данных тоже.
Уоррен Дью
2

Напоминаем, что не рекомендуется размещать кластеризованные индексы на случайных суррогатных ключах, т. Е. GUID, которые читают XY8D7-DFD8S, поскольку SQL Server не имеет возможности физически сортировать эти данные. Вместо этого вы должны поместить уникальные индексы в эти данные, хотя может быть также полезно просто запустить SQL Profiler для операций с основной таблицей и затем поместить эти данные в помощник по настройке ядра СУБД.

Смотрите ветку @ http://social.msdn.microsoft.com/Forums/en-us/sqlgetstarted/thread/27bd9c77-ec31-44f1-ab7f-bd2cb13129be

Брайан Свон
источник
Я уверен, что SQL Server может сортировать GUID.
Майкл Грин
Это не точно, хотя они могут оценить GUID, итоговая сортировка не является бессмысленной для человека. stackoverflow.com/questions/7810602/…
Брайан Свон
1
Истинное утверждение, но совершенно отличное от «SQL Server не имеет возможности физически сортировать их».
Майкл Грин
2

Случай 1: Ваша таблица является справочной таблицей с менее чем 50 типами (вставки)

Используйте бизнес / натуральные ключи . Например:

Table: JOB with 50 inserts
CODE (primary key)       NAME               DESCRIPTION
PRG                      PROGRAMMER         A programmer is writing code
MNG                      MANAGER            A manager is doing whatever
CLN                      CLEANER            A cleaner cleans
...............
joined with
Table: PEOPLE with 100000 inserts

foreign key JOBCODE in table PEOPLE
looks at
primary key CODE in table JOB

Случай 2: Ваш стол - это стол с тысячами вставок

Используйте суррогатные / автоинкрементные ключи . Например:

Table: ASSIGNMENT with 1000000 inserts
joined with
Table: PEOPLE with 100000 inserts

foreign key PEOPLEID in table ASSIGNMENT
looks at
primary key ID in table PEOPLE (autoincrement)

В первом случае:

  • Вы можете выбрать всех программистов в таблице PEOPLE без использования объединения с таблицей JOB, но только с помощью: "SELECT * FROM PEOPLE WHERE JOBCODE = 'PRG'"

Во втором случае:

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

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

Чарльз Грэм
источник
1

Лошадь для курсов. Чтобы заявить о моей предвзятости; Сначала я разработчик, поэтому я в основном заинтересован в том, чтобы предоставить пользователям работающее приложение.

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

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

Большинство традиционных разработчиков PL / SQL, с которыми я работал, не любили суррогатные ключи из-за количества таблиц в соединении, но наши тестовые и производственные базы данных никогда не вызывали проблем; дополнительные объединения не влияли на производительность приложения. В случае с диалектами базы данных, которые не поддерживают такие предложения, как «X внутреннее объединение Y на Xa = Yb», или разработчиками, которые не используют этот синтаксис, дополнительные объединения для суррогатных ключей затрудняют чтение запросов, а также их длительность при наборе и проверьте: см. сообщение Тони Эндрюса. Но если вы используете ORM или любую другую среду генерации SQL, вы этого не заметите. Сенсорный набор также смягчает.

WillC
источник
Также; если вы действительно хотите понять, что суррогатные ключи - это просто, начните их со случайного большого числа и увеличьте последовательности на 3+, а не на 1. Или используйте одну и ту же последовательность для генерации значений для более чем одного ключа.
WillC
1

Может быть, это не совсем относится к этой теме, но у меня болит голова с суррогатными ключами. Предварительно предоставленная Oracle аналитика создает автоматически сгенерированные SK на всех своих таблицах измерений в хранилище, а также сохраняет их на основе фактов. Таким образом, каждый раз, когда они (измерения) необходимо перезагружать при добавлении новых столбцов или заполнении для всех элементов в измерении, SK, назначенные во время обновления, делают SK не синхронизированными с исходными значениями, сохраненными в факте, заставляя полная перезагрузка всех таблиц фактов, которые к нему присоединяются. Я бы предпочел, чтобы даже если SK был бессмысленным числом, был бы какой-то способ, которым он не мог бы измениться для оригинальных / старых записей. Как многие знают, нестандартные решения редко служат потребностям организации, и нам приходится постоянно настраивать. Теперь у нас есть хранилище данных за 3 года, и полная перезагрузка из систем Oracle Financial очень велика. Так что в моем случае они не генерируются при вводе данных, а добавляются в хранилище, чтобы помочь составить отчет о производительности. Я понимаю, но наши меняются, и это кошмар.

LRB
источник
0

В случае базы данных на определенный момент времени лучше всего использовать комбинацию суррогатных и натуральных ключей. Например, вам необходимо отслеживать информацию о члене клуба. Некоторые атрибуты члена никогда не меняются. например, дата рождения, но имя может измениться. Поэтому создайте таблицу Member с суррогатным ключом member_id и создайте столбец для DOB. Создайте еще одну таблицу с именем person и добавьте столбцы для member_id, member_fname, member_lname, date_updated. В этой таблице естественным ключом будет member_id + date_updated.


источник