SQL: столбец первичного ключа. Столбец искусственного идентификатора против естественных столбцов [дубликаты]

Возможный дубликат:
реляционный вопрос о дизайне базы данных — суррогатный ключ или естественный ключ?

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

Действительно ли рекомендуется всегда предпочитать искусственные столбцы «Id» + индексы вместо естественных столбцов для первичного ключа?


person Andrew Florko    schedule 10.02.2011    source источник
comment
Иногда очень сложно определить ответ - настолько они все хороши :)   -  person Andrew Florko    schedule 10.02.2011
comment
Да, они есть, я согласен. =) И то, как работает ТАК, - это голосование и принятый ответ. Будьте рассудительны и выберите тот, который является более полным. Займите место новичка, прочитайте их и попытайтесь выяснить, из какого ответа вы узнали или могли бы узнать больше всего. Никто не будет злиться на вас! ;-) Кроме того, люди будут рады помочь вам, отвечая на ваши вопросы, когда у них больше шансов повысить свою репутацию (только когда они этого заслуживают). Берегите себя и хорошего дня/ночи! знак равно   -  person Will Marcouiller    schedule 11.02.2011


Ответы (6)


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

Если вы используете естественные ключи, двумя основными недостатками являются наличие составных ключей и изменение значений первичного ключа. Если у вас есть составные первичные ключи, вам, очевидно, придется иметь несколько столбцов в каждой дочерней таблице. Это может стать громоздким с точки зрения модели данных, когда между сущностями много отношений. Но это также может вызвать проблемы у людей, разрабатывающих запросы — очень легко создавать запросы, использующие N-1 из N условий соединения, и получать почти правильный результат. Если у вас есть естественные ключи, вы также неизбежно столкнетесь с ситуацией, когда значение естественного ключа изменится, и тогда вам придется распространить это изменение на множество различных сущностей — это намного сложнее, чем изменение уникального значения в таблице.

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

С точки зрения написания запросов и соглашения об именах я бы также предпочел синтетические ключи, потому что приятно знать, когда вы соединяете таблицы, что первичный ключ A будет A_ID, а первичный ключ B будет B_ID . Это намного лучше самодокументируется, чем попытка запомнить, что первичный ключ A — это комбинация A_NAME и A_REVISION_NUMBER, а первичный ключ B — это B_CODE.

person Justin Cave    schedule 10.02.2011

Существует небольшая разница между ключом, применяемым через ограничение PRIMARY KEY, и ключом, принудительно применяемым через ограничение UNIQUE. Важно то, что вы применяете ВСЕ ключи, необходимые с точки зрения целостности данных. Обычно это означает как минимум один "естественный" ключ (ключ, открытый пользователям/потребителям данных и используемый для идентификации фактов о вселенной дискурса) на таблицу.

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

person nvogel    schedule 10.02.2011

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

  • Маленький — чем меньше ключ, тем больше значений вы можете поместить в одну строку и тем быстрее будет сканирование индекса.
  • Стабильное увеличение — по мере роста таблицы производится меньшее количество перетасовок индексов, что повышает производительность.
person Thomas Rushton    schedule 10.02.2011

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

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

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

person Mayo    schedule 10.02.2011

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

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

person Will Marcouiller    schedule 10.02.2011

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

person chaos    schedule 10.02.2011
comment
Выставлять значимые ключи — не такая уж и плохая идея! Пользователям обычно нужны эти естественные ключи, чтобы идентифицировать во внешнем мире вещи, которые должна хранить база данных. Открытие ключей в пользовательском интерфейсе является неизбежным следствием точного представления информации и бизнес-правил. - person nvogel; 11.02.2011