Суррогатные и обычные / бизнес-ключи

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

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

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


person Manrico Corazzi    schedule 15.09.2008    source источник
comment
@Joachim Sauer: Спор о том, является ли вещь субъективной, может сам по себе быть субъективным, без какого-либо отношения к объективности или субъективности рассматриваемой вещи. Если вы не готовы указать точные объективные критерии, которые делают что-то объективным. Есть вещи, которые называются открытыми понятиями, например, сколько волос нужно, чтобы сделать бороду. Можно объективно сказать, что у человека без волос на подбородке нет бороды, а у человека с 5 000 волос на дюйм в длину есть борода, но где-то посередине требуется субъективное суждение, чтобы сделать объективное определение.   -  person ErikE    schedule 02.02.2010
comment
@Manrico: вы просто должны спросить себя: если я не использую суррогатный ключ, будет ли мой первичный ключ неизменным? Если ответ отрицательный, вам следует серьезно подумать об использовании суррогатного ключа. Кроме того, если первичный ключ хотя бы частично состоит из вводимых пользователем данных, вам следует рассмотреть возможность использования суррогатного ключа. Почему? Из-за опасности аномалий данных.   -  person code4life    schedule 19.05.2016
comment
@TylerRick Но это не совсем хороший вопрос. Он требует решения, которое обычно применимо ко всем ситуациям, когда явно его нет, что доказано религиозной войной, о которой спрашивающий прекрасно осведомлен (цитата: И снова, старый аргумент все еще возникает ...) . Вместо того, чтобы задаваться вопросом, изменился ли мир и, наконец, была предоставлена ​​веская причина для выбора одной стороны, лучше продолжать задавать этот вопрос снова и снова для каждой конкретной ситуации и публиковать в SO, если вы не уверены . Это просто обнажает догматизм.   -  person MarioDS    schedule 19.08.2016


Ответы (19)


Оба. Съешьте пирог и съешьте его.

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

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

person Ted    schedule 15.09.2008
comment
Если у вас есть несколько ключей-кандидатов (поля или коллекции полей одинакового размера, которые НЕ являются NULL UNIQUE), вы, вероятно, нарушаете нормальную форму Бойса-Кодда. BCNF выходит за рамки 3NF, поэтому не многие люди беспокоятся об этом. Однако бывают ситуации, когда пребывание в BCNF очень полезно. - person Alan; 17.09.2008
comment
Суррогатный ключ чрезвычайно полезен для работы с отношениями одиночный столбец и для приложений, которым необходимо иметь дело со связанными таблицами. Суррогатный ключ в обычном формате, опять же, полезен для таких вещей. Но, конечно, это не означает устранение ограничений для бизнеса. - person yfeldblum; 12.02.2009
comment
Согласованный. Настоящий вопрос должен заключаться в следующем: следует ли мне добавлять в свои таблицы уникальный суррогатный ключ? Совершенно другой вопрос - что использовать для логического первичного ключа. По сути, они оба являются ненулевыми ограничениями уникального индекса. - person dkretz; 13.02.2009
comment
Каждая проблема решается с помощью другого уровня косвенного обращения ... Суррогатные ключи - это всего лишь: другой уровень косвенного обращения - person Steve Schnepp; 29.05.2009
comment
Мне кажется странным, что многие комментарии, кажется, утверждают, что невозможно установить отношения без суррогатного ключа. Во многих случаях суррогатный ключ оказывается лишним. Зачем добавлять что-то, что не приносит ценности, но увеличивает технический долг (и в некоторых случаях приводит к тому, что уникальный результат внезапно становится неуникальным). - person Wil Moore III; 28.09.2010
comment
Верно. Не обобщая, но большинство людей в наши дни обычно склонны сводить варианты к черно-белому типу аргументов (НЕ плюс ультра ложных дилемм); и почти всегда ПРАВИЛЬНЫЙ ответ: ОБА. Съешьте пирог и тоже его съешьте. В поисках экономии ради нее мы склонны отбрасывать идеи и оставлять только одну, чтобы Править ими всеми. У обоих ключей есть причина для существования, и в большинстве современных бизнес-моделей они используются одновременно. - person alejandrob; 05.10.2015
comment
Это больше, чем ограничение NOT NULL UNIQUE. Первичный ключ используется в качестве кластерного индекса, который определяет физический порядок ваших данных. В общем, Integer легко сбалансировать, поскольку он увеличивается последовательно, и ваши данные будут добавлены в EOF на диске. Если вы используете менее последовательные данные, такие как текст или GUID (UUID), будет намного больше дискового ввода-вывода и усилий по балансированию индекса, я думаю, что это большая разница - person Jin; 02.05.2016

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

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

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

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

person Jay Shepherd    schedule 15.09.2008
comment
Теперь, прочитав много о суррогатных и естественных ключах, я думаю, что лучше использовать суррогатные ключи. Но в моей базе данных естественные ключи (NVARCHAR (20)) должны быть уникальными. Я не понимаю, как я могу увеличить скорость, если мне нужно проверять все данные в этом столбце, чтобы не повторять какое-либо значение (с использованием ограничения NOT NULL UNIQUE) для каждой вставки. - person VansFannel; 18.05.2016
comment
@VansFannel, насколько я знаю, index, созданный для обеспечения уникальности, позаботится о проверке повторений всякий раз, когда вы вставляете / обновляете значение. - person Ziyaddin Sadigov; 11.09.2020

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

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

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 и почтовый индекс. Я бы определенно использовал бессмысленный числовой ключ для таких таблиц, как Person, Address - но не для всего, что по некоторым причинам, кажется, защищает большинство здесь людей.

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

person Tony Andrews    schedule 12.02.2009
comment
-1 Естественные ключи в качестве первичного ключа имеют проблему, заключающуюся в том, что для каждой дочерней таблицы вам нужно добавить родительский ключ, который может состоять из более чем одного поля (вместо только одного, как в случае суррогатного ключа), а также дочернего ключ. Итак, представьте себе следующее, где, начиная с ТАБЛИЦЫ, отношение 1-0 .. *: ТАБЛИЦА PK: ID_A ТАБЛИЦА PK: ID_A ID_B ТАБЛИЦА PK: ID_A ID_B ID_C ТАБЛИЦА PK: ID_A ID_B ID_C ID_D. Видите проблему? Родительский ключ распространяется в дочерних таблицах. Что произойдет, если первичный ключ TABLEA изменится? Теперь вам придется также провести рефакторинг всех дочерних таблиц PK. - person Alfredo Osorio; 16.02.2012
comment
@Alfredo: да, конечно, есть компромисс. Однако за свой более чем 20-летний опыт я редко видел определение изменения PK таблицы. Если бы это происходило регулярно, я бы, вероятно, тоже избегал естественных ключей. На самом деле, в очень редких случаях, когда это случается, я готов выдержать длительный удар. - person Tony Andrews; 16.02.2012
comment
Это очень разумный ответ. Например, в настоящее время я пытаюсь разработать схему конечного автомата и могу выбрать либо UNIQUEIDENTIFIER, либо простой VARCHAR. В конце концов, какой из них более читабельный? SELECT ... FROM dbo.StateMachine WHERE id = '21556f00-9896-4455-ba26-cadea386d3cd' или ... WHERE id = 'registration'? Даже если вы называете их естественными ключами, многие из них в конечном итоге оказываются ключами технической идентификации, которые просто оказываются удобными. - person voithos; 21.09.2012
comment
Я не согласен. Часто бывает, что какой-то внешний орган (заказчик) предписывает отредактировать естественный ключ и, следовательно, распространить его по всей системе. Я вижу, что это происходит регулярно. Единственный способ быть уверенным в том, что ключ никогда не нужно будет менять, - это когда он по определению бессмысленен. Более того, современные базы данных очень эффективно обрабатывают внутренние соединения, поэтому потенциально большой выигрыш в пространстве от использования суррогатов обычно перевешивает преимущество отсутствия необходимости выполнять столько внутренних соединений. - person TTT; 18.12.2012
comment
@TTT: Тогда дизайн изначально был слабым. Опять же, именно здесь мужчины отделяются от мальчиков: они делают правильный выбор, когда использовать естественный ключ, а когда использовать суррогат. Вы решаете, что это для каждой таблицы, а не в качестве общей догмы. - person DanMan; 17.10.2013
comment
@DanMan: Я бы сказал, что все люди действительно сделали правильный выбор, когда использовать естественные ключи, скажем, в 99,9% случаев. Это 1/1000 раз, когда мужчины сделали неправильный выбор, когда мальчикам приходилось приходить и убирать беспорядок. - person TTT; 25.10.2013
comment
зачем вам это менять? потому что PHB, который не знает, о чем они говорят, говорит, что HR необходимо заменить на Human Resources. - person Shane; 14.01.2015
comment
У меня также есть более чем 20-летний опыт работы, и я согласен с вашим мнением. Однажды я создал хранилище данных Oracle с суррогатными ключами, и обслуживание данных было адским. Вы просто никогда не сможете напрямую получить доступ к своим данным. вам всегда нужно писать запросы ко всему, и это делает суррогатные ключи просто ужасными в обращении. - person SQL Police; 20.02.2016

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

person Rimantas    schedule 15.09.2008

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

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

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

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

person tzot    schedule 15.09.2008
comment
Вы выигрываете все интернет-сети с самым крутым именем пользователя! - person Iain Holder; 15.09.2008
comment
Если бы моя свекровь прочитала мой пост, она подумала бы: он не сказал, что поддерживает бизнес-ключи, поэтому он категорически против уникальных бизнес-ключей, поэтому он не должен жениться на моей дочери !; но она не будет это читать. Я считаю, что меня отвергли, потому что люди не соглашались со мной, а не потому, что это было бесполезно. - person tzot; 24.02.2009
comment
Это почти то же самое, что и отрицательный голос: я с этим не согласен. - person jcollum; 04.08.2009
comment
Всплывающая подсказка стрелки вниз говорит, что этот ответ бесполезен, я не согласен с этим. Возможно, в этом конкретном ответе значения близки, но в целом они не совпадают. - person tzot; 03.03.2010
comment
@jcollum: Думаю, вы никогда не читали мой предыдущий комментарий. - person tzot; 11.06.2010
comment
Если кто-то думает, что ваш ответ неверен, то он (/ она) также будет думать, что это ведет вопрошающего в неправильном направлении (противоположном правильному), и поэтому будет судить ваш ответ как даже хуже, чем бесполезный, оправдывающий в его (/ ее) мнение отрицательно. - person Erwin Smout; 02.11.2011
comment
@ErwinSmout: вы утверждаете очевидное, но спасибо. Итак, когда я говорю: «Первичный ключ таблицы должен использоваться для уникальной идентификации строки, в основном для целей соединения». (а затем приведите примеры), кто-то считает мой ответ неправильным и, следовательно, бесполезным; Я должен принять этот факт, не ожидая полезного аргумента. Правильно? - person tzot; 13.11.2011
comment
Как насчет решения сегодняшней проблемы сегодня и не беспокоиться так сильно о том, что может произойти в (далеком) будущем? ЯГНИ? - person Arne Evertsson; 14.12.2011
comment
Ага, суррогатные ключи - это болезнь. Один просачивается в дикую природу, и вы используете его как pkey, так что теперь вам нужен собственный суррогатный ключ. Затем ваш ключ просачивается в мир (скажем, через URL-адрес), и болезнь распространяется. - person Samuel Danielson; 05.10.2012

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

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

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

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

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

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

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

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

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

person Ken    schedule 28.09.2009
comment
Ненавижу суррогатные ключи, кроме случаев, когда они необходимы. Они необходимы, когда предприятие использует естественный ключ, который подвержен множеству ошибок, и не желает терпеть базу данных, на которую влияют эти ошибки. - person Walter Mitty; 18.09.2010
comment
-1: Я написал и поддержал десятки приложений. Больше всего проблем с данными испытывали те, у кого использовались естественные ключи. - person Falcon; 06.04.2011
comment
№6 - на самом деле довольно веский аргумент. Хотя я могу быть предвзятым, потому что мне не нравятся суррогатные ключи :) - person James King; 25.10.2011
comment
Добавление к 3 .: другими словами, вы сразу узнаете, какие поля обязательны в пользовательской форме, чтобы иметь возможность создать еще одну строку в таблице. - person DanMan; 17.10.2013
comment
Некоторые из ваших точек зрения предполагают, что суррогатный ключ должен быть PK или должен быть кластеризованным столбцом - это не так. Ваши пункты 1 и 5 игнорируют тот факт, что целые числа составляют 4 байта, а естественные ключи почти всегда много, намного больше байтов. И каждый некластеризованный индекс должен повторять байты тех естественных ключей, которые находятся в кластеризованном индексе, поэтому таблицы и индексы в вашей базе данных естественных ключей будут иметь гораздо, гораздо меньше строк на страницу, что переводится в много хуже скорость чтения, что делает запросы медленнее, а не быстрее. - person ErikE; 26.10.2013
comment
Еще одна причина против естественных ключей (примеры: атомные номера, VIN и т. Д.), Бизнес-логика может измениться, что увеличивает тип данных. Например - До: отслеживание зарядов атомов, После: отслеживание зарядов атомов и соединений. До: Отслеживание транспортных средств на предмет грузоподъемности. После: добавление самолетов, лодок, велосипедов и людей для определения грузоподъемности. - person forforf; 19.12.2013
comment
Я думаю, у вас нет таблиц, в которых первичный ключ хотя бы частично состоит из 1) любого атрибута, который может и будет изменяться) или 2) из ​​пользовательского ввода (например, динамически сгенерированных списков поиска). Если вы не можете гарантировать неизменность ключа, вам придется обновить все эти отношения сущностей с помощью кода или скриптов ручного исправления. Если вам никогда не приходилось этого делать ... Я полагаю, ваша база данных является одновременно суррогатной без ключа и ... необычной. - person code4life; 19.05.2016
comment
@Falcon, не могли бы вы рассказать больше о [приложениях], у которых больше всего проблем с данными использовалось при использовании естественных ключей? Например, почему возникли проблемы с данными? Какие проблемы? Как использование суррогатного ключа решит эти проблемы? - person Dennis; 19.04.2017
comment
@Dennis - Для меня было много случаев, когда мне приходилось изменять одно из значений NK из-за ошибки или деловой необходимости. Если бы я использовал схему использования NK в качестве PK (без суррогата), мне пришлось бы удалить и вставить соответствующую строку. Само по себе это не звучит ужасно, за исключением случаев, когда это FK другой таблицы. Обработка этого ключевого каскада (и его правильное выполнение) может быстро превратиться в кошмар. С суррогатным ключом мне нужно только одно обновление. - person StingyJack; 11.01.2019
comment
Причина № 6 - логическая ошибка. Просто потому, что этого нет в книге, это не значит, что это неверно или неверно. Следование этой логике приводит к каждой идее, о которой не было написано в книге, прежде чем она была задумана или замечена в другом месте как неправильная или ложная. - person StingyJack; 11.01.2019
comment
Правильное определение естественных ключей - это ключ :-) Индексы суррогатных ключей могут помочь вам быстрее выполнить JOIN, но будут бесполезны для оператора WHERE .... или как часто вы звоните своим детям по номерам ???? - person Mihail Gershkovich; 03.05.2021

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

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

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

Суррогатные ключи:

  1. Source of performance problems:
    • They are usually implemented using auto-incremented columns which mean:
      • A round-trip to the database each time you want to get a new Id (I know that this can be improved using caching or [seq]hilo alike algorithms but still those methods have their own drawbacks).
      • Если в один прекрасный день вам нужно переместить данные из одной схемы в другую (по крайней мере, в моей компании это происходит довольно регулярно), вы можете столкнуться с проблемами коллизии идентификаторов. И да, я знаю, что вы можете использовать UUID, но для этого требуется 32 шестнадцатеричных цифры! (Если вам важен размер базы данных, это может быть проблемой).
      • Если вы используете одну последовательность для всех своих суррогатных ключей, то - наверняка - вы столкнетесь с конфликтом в своей базе данных.
  2. Error prone. A sequence has a max_value limit so - as a developer - you have to put attention to the following points:
    • You must cycle your sequence ( when the max-value is reached it goes back to 1,2,...).
    • Если вы используете последовательность как упорядочение (во времени) ваших данных, вы должны обработать случай циклического изменения (столбец с идентификатором 1 может быть новее, чем строка с максимальным значением идентификатора - 1).
    • Убедитесь, что ваш код (и даже ваши клиентские интерфейсы, которых не должно происходить, поскольку это должен быть внутренний идентификатор) поддерживает целые числа 32b / 64b, которые вы использовали для хранения значений вашей последовательности.
  3. Они не гарантируют отсутствие дублирования данных. У вас всегда может быть 2 строки со всеми одинаковыми значениями столбцов, но с другим сгенерированным значением. Для меня это САМАЯ проблема суррогатных ключей с точки зрения дизайна базы данных.
  4. Больше в Википедии ...

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

  1. Composite keys are less inefficient than surrogate keys. No! It depends on the used database engine:
  2. Естественных ключей в реальной жизни не существует. Извините, но они существуют! В авиационной отрасли, например, следующий кортеж всегда будет уникальным для данного регулярного рейса (авиакомпания, Дата отправления, номер рейса, Операционный суффикс). В более общем плане, когда набор бизнес-данных гарантированно уникален заданным стандартом, тогда этот набор данных является [хорошим] естественным ключевым кандидатом.
  3. Естественные ключи «загрязняют схему» дочерних таблиц. Для меня это больше чувство, чем реальная проблема. Первичный ключ из 4 столбцов по 2 байта может быть более эффективным, чем один столбец из 11 байтов. Кроме того, 4 столбца можно использовать для прямого запроса дочерней таблицы (используя 4 столбца в предложении where) без присоединения к родительской таблице.

Вывод

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

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

person mwnsiri    schedule 27.12.2013
comment
Что происходит, когда дата вылета обычного рейса переносится? Вам нужно отслеживать все связанные объекты и удалять ключи, или вы действительно обновляете все ключи в связанных объектах? Или вы имеете дело с простой, единственной таблицей (возможно, даже не с 3NF)? - person code4life; 19.05.2016
comment
Отличная точка @ code4life - person forcewill; 15.07.2016
comment
@ code4life: Вот здесь и появляется операционный суффикс. Чтобы сохранить тот же номер полета и избежать путаницы с клиентом, мы добавляем только суффикс (например, «D»). - person mwnsiri; 21.07.2016
comment
У вас всегда может быть 2 строки со всеми одинаковыми значениями столбцов, но с другим сгенерированным значением, поэтому просто установите уникальное или составное уникальное ограничение на свои столбцы. - person wha7ever; 13.09.2019
comment
Зачем иметь первичный индекс для автоматически сгенерированного значения И уникальный индекс для естественного ключа, если вы можете сохранить только один? - person mwnsiri; 25.12.2020
comment
Есть еще одна вещь: в СУБД, предлагающих ENUMS, вы можете использовать ENUMS для значений PK / FK, если количество значений поиска не превышает ~ 65k, так что они будут использовать 1-2 байта. Прибыль превыше прибыли .... - person Mihail Gershkovich; 03.05.2021

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

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

person Iain Holder    schedule 15.09.2008
comment
Мартин Фаулер может быть многим, но он не специалист в области проектирования баз данных. - person Tony Andrews; 02.06.2009
comment
Я думаю, вам следует привести некоторые аргументы, прежде чем прийти к заключению. - person Arne Evertsson; 14.12.2011
comment
@ArneEvertsoon Причина там. «Все сводится к тому, что у него должна быть одна работа и только одна работа». Единоличная ответственность. - person Iain Holder; 14.12.2011

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

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

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

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

person Derek Lawless    schedule 15.09.2008

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

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

person Mark Embling    schedule 15.09.2008
comment
К сожалению, у автомобилей действительно есть естественный ключ, который не меняется: VIN (по крайней мере, в Америке ...) - person jcollum; 04.08.2009
comment
@jcollum Да ладно, это справедливый вопрос. Мое мнение все еще остается в силе, мой пример не обязательно был настолько хорош, насколько мог бы быть. - person Mark Embling; 10.08.2009
comment
Список языков будет примером естественного ключа, если вы основываете его на кодах ISO. Поэтому, если вы затем захотите загрузить содержимое из таблицы на определенном языке, вам не нужно будет присоединяться к таблице languages, поскольку код языка (ID) уже находится в таблице texts. - person DanMan; 17.10.2013
comment
@DanMan Я должен с вами согласиться. Всегда найдутся примеры, которые лучше работают с естественным ключом. Правила или общие подходы никогда не бывают абсолютными, и это один из примеров, который я бы на 100% согласился с вашим подходом :-) - person Mark Embling; 17.10.2013

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

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

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

person user7658    schedule 15.09.2008

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

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

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

В этом случае используйте ключи с именами вручную в соответствии со значением каждой записи.

Например:

Table: JOB with 50 records
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 records
joined with
Table: PEOPLE with 100000 records

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

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

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

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

  • Ваши запросы к базе данных выполняются быстрее, потому что ваш первичный ключ является целым числом
  • Вам не нужно беспокоиться о поиске следующего уникального ключа, потому что сама база данных дает вам следующий автоинкремент.
person Stefanos Kargas    schedule 24.10.2012

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

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

person David Thornley    schedule 12.02.2009
comment
Думаю, я не могу согласиться с вашим примером здесь. Номер ISBN - это атрибут книги. Суррогатный ключ не зависит от остальных данных строки, поэтому в этой позиции рекомендуется использовать отдельный суррогатный ключ для таблицы книги, даже если ISBN уже однозначно идентифицирует каждую книгу. - person Christopher Cashell; 01.04.2010
comment
В качестве альтернативы можно рассматривать ISBN как суррогатный ключ. Это не имеющий значения идентификатор, просто код, который применяется к конкретной книге. Если вы составляете таблицу с книгами, ISBN также может быть первичным ключом (при условии, что у вас есть и всегда будет по одной книге на строку). - person David Thornley; 01.04.2010
comment
@Christopher Cashell - наткнулся на этот пост год назад, но подумал добавить что-нибудь. Не гарантируется, что номера ISBN уникальны и могут иметь дубликаты. У меня есть друг, который проработал в библиотеке несколько лет, и ему часто попадались книги с повторяющимися номерами ISBN. Проблема в том, что уникальность ISBN лежит на издателе, а не на одном органе, который гарантирует, что все номера для всех публикаций уникальны, и эти издатели не всегда действовали сообща. - person Thomas; 22.04.2011
comment
Наткнулся на этот пост год назад и хотел упомянуть, что ISBN на самом деле являются естественными ключами. В отличие от суррогатного ключа, в самом значении ключа есть смысл. Например, часть ключа идентифицирует издателя. Кроме того, как я упоминал выше, их уникальность не гарантируется. Они предполагаются уникальными, но эта уникальность исходит от издателей, и они не всегда были идеальными. - person Thomas; 22.04.2011
comment
Технически корпорации не могут перемещаться между штатами; происходит то, что в новом государстве создается новая корпорация и передаются активы. Это работает и для информации из базы данных. - person Warren Dew; 04.05.2014

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

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

person Bryan Swan    schedule 27.06.2012
comment
Я почти уверен, что SQL Server может сортировать идентификаторы GUID. - person Michael Green; 14.09.2016
comment
Это неточно, хотя они могут оценить GUID, полученная в результате сортировка не является бессмысленной для человека. stackoverflow.com/questions/7810602/ - person Bryan Swan; 08.10.2016
comment
Верное утверждение, но совершенно отличное от того, что SQL Server не имеет возможности их физически отсортировать. - person Michael Green; 10.10.2016

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

person Charles Graham    schedule 15.09.2008

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

person Community    schedule 07.03.2009

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

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

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

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

person WillC    schedule 09.02.2012
comment
Также; если вы действительно хотите убедить вас, что суррогатные ключи - это просто так, начните их со случайного большого числа и увеличивайте последовательности на 3+, а не на 1. Или используйте ту же последовательность для генерации значений для более чем одного ключа. - person WillC; 10.02.2012
comment
КАСКАД НА ОБНОВЛЕНИЕ, и ваша СУБД позаботится обо всех изменениях .... - person Mihail Gershkovich; 03.05.2021

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

person lrb    schedule 24.04.2013