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

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

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

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

@Joachim Sauer: Спор о том, является ли вещь субъективной, может быть сам по себе субъективным, без какого-либо отношения к объективности или субъективности рассматриваемой вещи. Если вы не готовы указать точные объективные критерии, которые делают что-то объективным. Есть вещи, которые называются «открытыми понятиями», например, сколько волосков нужно, чтобы сделать бороду. Можно объективно сказать, что у человека без волос на подбородке нет бороды, а у человека с 5 000 волос на дюйм в длину есть борода, но где-то посередине требуется субъективное суждение, чтобы сделать объективное определение.

ErikE 02.02.2010 21:42

@Manrico: вы просто должны спросить себя: если я не буду использовать суррогатный ключ, будет ли мой первичный ключ неизменным? Если ответ отрицательный, то серьезно следует рассмотреть возможность использования суррогатного ключа. Кроме того, если первичный ключ хотя бы частично состоит из вводимых пользователем данных, вам следует рассмотреть возможность использования суррогатного ключа. Почему? Из-за опасности аномалий данных.

code4life 19.05.2016 03:42

@TylerRick Но это не совсем хороший вопрос. Он требует решения, которое обычно применимо ко всем ситуациям, когда явно его нет, что доказано «религиозной войной», о которой спрашивающий прекрасно осведомлен (цитата: «И снова, старый аргумент все еще возникает. .. "). Вместо того, чтобы задаваться вопросом, изменился ли мир и, наконец, была предоставлена ​​веская причина выбрать одну сторону, лучше продолжать задавать этот вопрос снова и снова для каждой конкретной ситуации и публиковать в SO, если вы не уверены . Это просто обнажает догматизм.

MarioDS 19.08.2016 18:33
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
183
3
70 467
19
Перейти к ответу Данный вопрос помечен как решенный

Ответы 19

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

Обновлено: Я пытался найти ссылку на него в Интернете, но не смог. Однако в 'Паттерны корпоративной архитектуры' [Fowler] есть хорошее объяснение того, почему вы не должны использовать ничего, кроме ключа, не имеющего никакого значения, кроме ключа. Это сводится к тому, что у него должна быть одна работа и только одна работа.

Мартин Фаулер может быть многим, но он не специалист по проектированию баз данных.

Tony Andrews 02.06.2009 16:25

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

Arne Evertsson 14.12.2011 09:50

@ArneEvertsoon Причина там. «Все сводится к тому, что у него должна быть одна работа и только одна работа». Единоличная ответственность.

Iain Holder 14.12.2011 14:50

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

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

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

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

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

К сожалению, у автомобилей действительно есть естественный ключ, который не меняется: VIN (по крайней мере, в Америке ...)

jcollum 04.08.2009 21:22

@jcollum Да ладно, это справедливый вопрос. Мое мнение все еще остается в силе, мой пример не обязательно был настолько хорош, насколько мог бы быть.

Mark Embling 10.08.2009 12:57

Список языков будет примером естественного ключа, если вы основываете его на кодах ISO. Поэтому, если вы затем захотите загрузить содержимое из таблицы на определенном языке, вам не нужно присоединяться к таблице languages, поскольку код языка (ID) уже находится в таблице texts.

DanMan 17.10.2013 21:40

@DanMan Я должен с тобой согласиться. Всегда найдутся примеры, которые лучше работают с естественным ключом. Правила или общие подходы никогда не бывают абсолютными, и это один из примеров, который я бы на 100% согласился с вашим подходом :-)

Mark Embling 17.10.2013 22:27

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

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

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

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

Вы выигрываете все интернет-сети с самым крутым именем пользователя!

Iain Holder 15.09.2008 18:05

Если бы моя свекровь прочитала мой пост, она подумала бы: «Он не говорил, что поддерживает бизнес-ключи, поэтому он категорически против уникальных бизнес-ключей, поэтому он не должен жениться на моей дочери!»; но она не будет это читать. Я считаю, что меня отвергли, потому что люди не соглашались со мной, а не потому, что это было бесполезно.

tzot 24.02.2009 03:11

Это почти то же самое, что и отрицательный голос: «Я не согласен с этим».

jcollum 04.08.2009 21:23

Всплывающая подсказка стрелки вниз говорит: «Этот ответ бесполезен», а не «Я не согласен с этим». Возможно, в этом конкретном ответе значения близки, но в целом они не совпадают.

tzot 03.03.2010 05:11

@jcollum: Думаю, вы никогда не читали мой предыдущий комментарий.

tzot 11.06.2010 21:50

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

Erwin Smout 02.11.2011 17:42

@ErwinSmout: вы утверждаете очевидное, но спасибо. Итак, когда я говорю: «Первичный ключ таблицы должен использоваться для уникальной идентификации строки, в основном для целей соединения». (а затем приведите примеры), кто-то считает мой ответ неправильным и, следовательно, бесполезным; Я должен принять этот факт, не ожидая полезного аргумента. Правильно?

tzot 13.11.2011 12:13

Как насчет решения сегодняшней проблемы сегодня и не беспокоиться так сильно о том, что может произойти в (далеком) будущем? ЯГНИ?

Arne Evertsson 14.12.2011 09:44

Ага, суррогатные ключи - это болезнь. Один утекает в дикую природу, и вы используете его как pkey, так что теперь вам нужен собственный суррогатный ключ. Затем ваш ключ утекает в дикую природу (например, через URL-адрес), и болезнь распространяется.

Samuel Danielson 05.10.2012 19:16

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

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

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

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

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

VansFannel 18.05.2016 10:39

@VansFannel, насколько я знаю, index, созданный для обеспечения уникальности, позаботится о проверке повторений всякий раз, когда вы вставляете / обновляете значение.

Ziyaddin Sadigov 11.09.2020 20:27

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

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

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

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

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

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

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

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

Ответ принят как подходящий

Обе. Ешь свой торт и ешь.

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

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

Если у вас есть несколько ключей-кандидатов (поля или коллекции полей одинакового размера, которые НЕ являются NULL UNIQUE), вы, вероятно, нарушаете нормальную форму Бойса-Кодда. BCNF выходит за рамки 3NF, поэтому не многие люди беспокоятся об этом. Однако бывают ситуации, когда пребывание в BCNF очень полезно.

Alan 17.09.2008 21:19

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

yfeldblum 12.02.2009 18:00

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

dkretz 13.02.2009 01:11

«Каждая проблема решается с помощью другого уровня косвенного обращения» ... Суррогатные ключи - это всего лишь: уровень косвенного обращения еще один

Steve Schnepp 29.05.2009 15:10

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

Wil Moore III 28.09.2010 10:55

В самом деле. Не обобщая, но большинство людей в наши дни обычно склонны сводить варианты к черно-белому типу аргументов (НЕ плюс ультра ложных дилемм); и почти всегда ПРАВИЛЬНЫЙ ответ таков: «ОБА. Съешьте свой пирог и съешьте его тоже». В поисках экономии ради нее мы склонны отбрасывать идеи и оставлять только одну, чтобы Править ими всеми. У обоих ключей есть причина для существования, и в большинстве современных бизнес-моделей они используются одновременно.

alejandrob 05.10.2015 17:21

Это больше, чем ограничение NOT NULL UNIQUE. Первичный ключ используется в качестве кластерного индекса, который определяет физический порядок ваших данных. В общем, Integer легко сбалансировать, поскольку он увеличивается последовательно, и ваши данные будут добавлены в EOF на диске. Если вы используете менее последовательные данные, такие как текст или GUID (UUID), будет намного больше дискового ввода-вывода и усилий по балансированию индекса, я думаю, что это большая разница

Jin 02.05.2016 23:42

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

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

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

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

-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.

Alfredo Osorio 16.02.2012 03:28

@Alfredo: да, конечно, есть компромисс. Однако за свой более чем 20-летний опыт я редко видел определение изменения PK таблицы. Если бы это происходило регулярно, я бы, вероятно, тоже избегал естественных ключей. На самом деле, в очень редких случаях, когда это случается, я готов выдержать длительный удар.

Tony Andrews 16.02.2012 14:18

Это очень разумный ответ. Например, в настоящее время я пытаюсь разработать схему конечного автомата, и у меня есть возможность выбрать либо UNIQUEIDENTIFIER, либо простой VARCHAR. В конце концов, какой из них более читабельный? SELECT ... FROM dbo.StateMachine WHERE id = '21556f00-9896-4455-ba26-cadea386d3cd' или ... WHERE id = 'registration'? Даже если вы называете их «естественными ключами», многие из них в конечном итоге оказываются ключами технической идентификации, которые просто оказываются удобными.

voithos 21.09.2012 20:40

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

TTT 18.12.2012 02:53

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

DanMan 17.10.2013 21:25

@DanMan: Я бы сказал, что все люди действительно сделали правильный выбор, когда использовать естественные ключи, скажем, в 99,9% случаев. Это 1/1000 раз, когда мужчины сделали неправильный выбор, когда мальчикам приходилось приходить и убирать беспорядок.

TTT 25.10.2013 22:18

"зачем вам это менять?" потому что PHB, который не знает, о чем они говорят, говорит, что HR необходимо заменить на Human Resources.

Shane 14.01.2015 18:11

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

SQL Police 20.02.2016 01:58

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

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

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

Christopher Cashell 01.04.2010 01:28

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

David Thornley 01.04.2010 02:08

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

Thomas 22.04.2011 08:49

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

Thomas 22.04.2011 08:52

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

Warren Dew 04.05.2014 05:28

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

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

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

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

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

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

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

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

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

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

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

Walter Mitty 18.09.2010 15:06

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

Falcon 06.04.2011 17:58

№6 - на самом деле довольно веский аргумент. Хотя я могу быть предвзятым, потому что мне не нравятся суррогатные ключи :)

James King 25.10.2011 21:01
google.pl/search?q=surrogate+keys&tbm=bks&tbo=1 ;)
Robert Bak 07.02.2012 23:14

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

DanMan 17.10.2013 21:34

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

ErikE 26.10.2013 06:05

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

forforf 19.12.2013 01:15

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

code4life 19.05.2016 03:46

@Falcon, не могли бы вы рассказать больше о «[приложениях] с наибольшим количеством проблем, связанных с данными, были те, которые использовали естественные ключи»? Например, почему возникли проблемы с данными? Какие проблемы? Как использование суррогатного ключа решит эти проблемы?

Dennis 19.04.2017 17:31

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

StingyJack 11.01.2019 17:30

Причина № 6 - логическая ошибка. Просто потому, что этого нет в книге, это не значит, что это неверно или неверно. Следование этой логике приводит к каждой идее, о которой не было написано в книге, прежде чем она была задумана или замечена в другом месте как неправильная или ложная.

StingyJack 11.01.2019 17:34

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

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

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

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

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

WillC 10.02.2012 03:05

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

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

Я почти уверен, что SQL Server может сортирует GUID.

Michael Green 14.09.2016 15:11

Это неточно, хотя они могут оценить GUID, полученная сортировка не является бессмысленной для человека. stackoverflow.com/questions/7810602/…

Bryan Swan 08.10.2016 18:13

Верное утверждение, но совершенно иное, чем «SQL Server не имеет возможности физически отсортировать их».

Michael Green 10.10.2016 03:02

Случай 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'

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

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

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

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

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

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

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

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

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

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

Вывод

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

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

Что происходит, когда дата вылета обычного рейса переносится? Вам нужно отслеживать все связанные объекты и удалять ключи, или вы действительно обновляете все ключи в связанных объектах? Или вы имеете дело с простой, единственной таблицей (возможно, даже не с 3NF)?

code4life 19.05.2016 03:48

Отличный момент @ code4life

forcewill 15.07.2016 14:10

@ code4life: Вот здесь и появляется операционный суффикс. Чтобы сохранить тот же номер рейса и избежать путаницы с клиентом, мы добавляем только суффикс (например, «D»).

mwnsiri 21.07.2016 15:37

«У вас всегда может быть 2 строки со всеми одинаковыми значениями столбцов, но с другим сгенерированным значением», поэтому просто установите уникальное или составное уникальное ограничение на свои столбцы.

wha7ever 13.09.2019 22:46

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

mwnsiri 25.12.2020 00:34

Другие вопросы по теме