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

Всегда используйте ключ, не имеющий коммерческого значения. Это просто хорошая практика.
Обновлено: Я пытался найти ссылку на него в Интернете, но не смог. Однако в 'Паттерны корпоративной архитектуры' [Fowler] есть хорошее объяснение того, почему вы не должны использовать ничего, кроме ключа, не имеющего никакого значения, кроме ключа. Это сводится к тому, что у него должна быть одна работа и только одна работа.
Мартин Фаулер может быть многим, но он не специалист по проектированию баз данных.
Я думаю, вам следует привести некоторые аргументы, прежде чем прийти к заключению.
@ArneEvertsoon Причина там. «Все сводится к тому, что у него должна быть одна работа и только одна работа». Единоличная ответственность.
У суррогатного ключа НИКОГДА не будет причин для изменения. Я не могу сказать того же о естественных ключах. Фамилии, адреса электронной почты, номера ISBN - все это может измениться в один прекрасный день.
Я считаю, что в сценарии хранилища данных лучше следовать пути суррогатного ключа. Две причины:
На мой взгляд, лучше использовать суррогатный ключ, поскольку вероятность его изменения равна нулю. Почти все, что я могу придумать, что вы можете использовать в качестве естественного ключа, может измениться (отказ от ответственности: не всегда верно, но обычно).
Примером может служить база данных автомобилей - на первый взгляд может показаться, что номерной знак можно использовать в качестве ключа. Но их можно изменить, так что это плохая идея. Вы действительно не захотите узнать об этом, когда после выпускает приложение, когда кто-то приходит к вам, желая узнать, почему они не могут изменить свой номерной знак на свой новый блестящий персонализированный.
К сожалению, у автомобилей действительно есть естественный ключ, который не меняется: VIN (по крайней мере, в Америке ...)
@jcollum Да ладно, это справедливый вопрос. Мое мнение все еще остается в силе, мой пример не обязательно был настолько хорош, насколько мог бы быть.
Список языков будет примером естественного ключа, если вы основываете его на кодах ISO. Поэтому, если вы затем захотите загрузить содержимое из таблицы на определенном языке, вам не нужно присоединяться к таблице languages, поскольку код языка (ID) уже находится в таблице texts.
@DanMan Я должен с тобой согласиться. Всегда найдутся примеры, которые лучше работают с естественным ключом. Правила или общие подходы никогда не бывают абсолютными, и это один из примеров, который я бы на 100% согласился с вашим подходом :-)
Суррогатные ключи (обычно целые числа) имеют добавленную стоимость, ускоряя отношения между таблицами и делая их более экономичными с точки зрения хранения и скорости обновления (что еще лучше, внешние ключи не нужно обновлять при использовании суррогатных ключей, в отличие от полей бизнес-ключей, которые время от времени меняются).
Первичный ключ таблицы следует использовать для однозначной идентификации строки, в основном для целей соединения. Представьте себе таблицу лиц: имена могут меняться, и их уникальность не гарантируется.
Думайте о компаниях: вы счастливы, что компания Merkin ведет дела с другими компаниями в Merkia. Вы достаточно умны, чтобы не использовать название компании в качестве первичного ключа, поэтому вы используете уникальный правительственный идентификатор компании Merkia, состоящий из 10 буквенно-цифровых символов. Затем Merkia меняет идентификаторы компании, потому что они думали, что это будет хорошая идея. Ничего страшного, вы используете функцию каскадных обновлений вашего движка db для изменения, которое не должно касаться вас в первую очередь. Позже ваш бизнес расширяется, и теперь вы работаете с компанией во Фридонии. Идентификатор компании Freedonian может содержать до 16 символов. Вам необходимо увеличить первичный ключ идентификатора компании (а также поля внешнего ключа в Order, Issues, MoneyTransfers и т. д.), Добавив поле Country в первичный ключ (также во внешние ключи). Ой! Гражданская война во Фридонии, она расколота на три страны. Название страны вашего сотрудника следует изменить на новое; каскадные обновления приходят на помощь. Кстати, какой у вас первичный ключ? (Country, CompanyID) или (CompanyID, Country)? Последний помогает присоединяться, первый избегает другого индекса (или, возможно, многих, если вы хотите, чтобы ваши заказы также были сгруппированы по странам).
Все это не доказательство, а указание на то, что суррогатный ключ для однозначной идентификации строки для всех применений, включая операции соединения, предпочтительнее бизнес-ключа.
Вы выигрываете все интернет-сети с самым крутым именем пользователя!
Если бы моя свекровь прочитала мой пост, она подумала бы: «Он не говорил, что поддерживает бизнес-ключи, поэтому он категорически против уникальных бизнес-ключей, поэтому он не должен жениться на моей дочери!»; но она не будет это читать. Я считаю, что меня отвергли, потому что люди не соглашались со мной, а не потому, что это было бесполезно.
Это почти то же самое, что и отрицательный голос: «Я не согласен с этим».
Всплывающая подсказка стрелки вниз говорит: «Этот ответ бесполезен», а не «Я не согласен с этим». Возможно, в этом конкретном ответе значения близки, но в целом они не совпадают.
@jcollum: Думаю, вы никогда не читали мой предыдущий комментарий.
Если кто-то думает, что ваш ответ неправильный, то он (/ она) также будет думать, что это ведет вопрошающего в неправильном направлении (противоположном правильному), и, следовательно, сочтет ваш ответ даже хуже, чем «бесполезный», оправдывая в своем уме голос против.
@ErwinSmout: вы утверждаете очевидное, но спасибо. Итак, когда я говорю: «Первичный ключ таблицы должен использоваться для уникальной идентификации строки, в основном для целей соединения». (а затем приведите примеры), кто-то считает мой ответ неправильным и, следовательно, бесполезным; Я должен принять этот факт, не ожидая полезного аргумента. Правильно?
Как насчет решения сегодняшней проблемы сегодня и не беспокоиться так сильно о том, что может произойти в (далеком) будущем? ЯГНИ?
Ага, суррогатные ключи - это болезнь. Один утекает в дикую природу, и вы используете его как pkey, так что теперь вам нужен собственный суррогатный ключ. Затем ваш ключ утекает в дикую природу (например, через URL-адрес), и болезнь распространяется.
Вот несколько причин для использования суррогатных ключей:
Стабильность: изменение ключа из-за деловой или естественной потребности отрицательно повлияет на связанные таблицы. Суррогатные ключи редко, если вообще когда-либо, нужно менять, потому что значение не привязано к значению.
соглашение: позволяет использовать стандартизированное соглашение об именах столбцов первичного ключа вместо того, чтобы думать о том, как объединить таблицы с различными именами для их PK.
Скорость: в зависимости от значения и типа PK суррогатный ключ целого числа может быть меньше, что позволяет быстрее индексировать и искать.
Теперь, прочитав много о суррогатных и естественных ключах, я думаю, что лучше использовать суррогатные ключи. Но в моей базе данных естественные ключи (NVARCHAR (20)) должны быть уникальными. Я не понимаю, как можно увеличить скорость, если мне нужно проверять все данные в этом столбце, чтобы не повторять какое-либо значение (с использованием ограничения NOT NULL UNIQUE) при каждой вставке.
@VansFannel, насколько я знаю, index, созданный для обеспечения уникальности, позаботится о проверке повторений всякий раз, когда вы вставляете / обновляете значение.
Это один из тех случаев, когда суррогатный ключ всегда имеет смысл. Бывают случаи, когда вы либо выбираете то, что лучше всего для базы данных, либо то, что лучше всего для вашей объектной модели, но в обоих случаях лучше использовать бессмысленный ключ или GUID. Это упрощает и ускоряет индексацию, и это идентичность вашего объекта, которая не меняется.
Суррогатные ключи очень удобны, если вы планируете использовать ORM-инструмент для обработки / генерации ваших классов данных. Хотя вы можете использовать составные ключи с некоторыми из более продвинутых мапперов (читай: спящий режим), это добавляет сложности к вашему коду.
(Конечно, сторонники чистоты баз данных будут утверждать, что даже понятие суррогатного ключа является мерзостью.)
Я фанат использования uids для суррогатных ключей, когда это возможно. Их главный выигрыш в том, что вы знаете ключ заранее, например. вы можете создать экземпляр класса с уже установленным идентификатором и гарантированно быть уникальным, тогда как, скажем, с целочисленным ключом вам нужно будет по умолчанию установить значение 0 или -1 и обновить до соответствующего значения при сохранении / обновлении.
У идентификаторов UID есть штрафы с точки зрения скорости поиска и присоединения, поэтому от конкретного приложения зависит, являются ли они желательными.
По возможности всегда используйте суррогатный ключ из одного столбца. Это делает соединения, а также вставки / обновления / удаления намного чище, потому что вы несете ответственность только за отслеживание одного фрагмента информации для поддержания записи.
Затем, при необходимости, сложите свои бизнес-ключи в виде уникальных ограничений или индексов. Это сохранит целостность ваших данных.
Бизнес-логика / естественные ключи могут изменяться, но физический ключ таблицы НИКОГДА не должен меняться.
Обе. Ешь свой торт и ешь.
Помните, что в первичном ключе нет ничего особенного, за исключением того, что он помечен как таковой. Это не что иное, как ограничение NOT NULL UNIQUE, а в таблице может быть больше одного.
Если вы используете суррогатный ключ, вам все равно нужен бизнес-ключ, чтобы гарантировать уникальность в соответствии с бизнес-правилами.
Если у вас есть несколько ключей-кандидатов (поля или коллекции полей одинакового размера, которые НЕ являются NULL UNIQUE), вы, вероятно, нарушаете нормальную форму Бойса-Кодда. BCNF выходит за рамки 3NF, поэтому не многие люди беспокоятся об этом. Однако бывают ситуации, когда пребывание в BCNF очень полезно.
Суррогатный ключ чрезвычайно полезен для работы с отношениями Один-столбца и для приложений, которым необходимо иметь дело со связанными таблицами. Суррогатный ключ в обычном формате, опять же, полезен для таких вещей. Но, конечно, это не означает устранение ограничений для бизнеса.
Согласовано. Настоящий вопрос должен заключаться в следующем: следует ли мне добавлять в свои таблицы уникальный суррогатный ключ? Совершенно другой вопрос - что использовать для логического первичного ключа. По сути, они оба являются ненулевыми ограничениями уникального индекса.
«Каждая проблема решается с помощью другого уровня косвенного обращения» ... Суррогатные ключи - это всего лишь: уровень косвенного обращения еще один
Мне кажется странным, что многие комментарии, кажется, утверждают, что невозможно установить отношения без суррогатного ключа. Во многих случаях суррогатный ключ оказывается лишним. Зачем добавлять что-то, что не приносит никакой ценности, но добавляет технический долг (и в некоторых случаях приводит к тому, что уникальный результат внезапно становится неуникальным).
В самом деле. Не обобщая, но большинство людей в наши дни обычно склонны сводить варианты к черно-белому типу аргументов (НЕ плюс ультра ложных дилемм); и почти всегда ПРАВИЛЬНЫЙ ответ таков: «ОБА. Съешьте свой пирог и съешьте его тоже». В поисках экономии ради нее мы склонны отбрасывать идеи и оставлять только одну, чтобы Править ими всеми. У обоих ключей есть причина для существования, и в большинстве современных бизнес-моделей они используются одновременно.
Это больше, чем ограничение NOT NULL UNIQUE. Первичный ключ используется в качестве кластерного индекса, который определяет физический порядок ваших данных. В общем, Integer легко сбалансировать, поскольку он увеличивается последовательно, и ваши данные будут добавлены в EOF на диске. Если вы используете менее последовательные данные, такие как текст или GUID (UUID), будет намного больше дискового ввода-вывода и усилий по балансированию индекса, я думаю, что это большая разница
Похоже, что никто еще ничего не сказал в поддержку несуррогатных (я не решаюсь сказать «естественных») ключей. Итак, начнем ...
недостаток суррогатных ключей - это бессмысленный (некоторые считают его преимуществом, но ...). Иногда это заставляет вас присоединять к вашему запросу гораздо больше таблиц, чем действительно необходимо. Сравнивать:
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: да, конечно, есть компромисс. Однако за свой более чем 20-летний опыт я редко видел определение изменения PK таблицы. Если бы это происходило регулярно, я бы, вероятно, тоже избегал естественных ключей. На самом деле, в очень редких случаях, когда это случается, я готов выдержать длительный удар.
Это очень разумный ответ. Например, в настоящее время я пытаюсь разработать схему конечного автомата, и у меня есть возможность выбрать либо UNIQUEIDENTIFIER, либо простой VARCHAR. В конце концов, какой из них более читабельный? SELECT ... FROM dbo.StateMachine WHERE id = '21556f00-9896-4455-ba26-cadea386d3cd' или ... WHERE id = 'registration'? Даже если вы называете их «естественными ключами», многие из них в конечном итоге оказываются ключами технической идентификации, которые просто оказываются удобными.
Я не согласен. Часто случается, что какой-то внешний орган (заказчик) предписывает отредактировать естественный ключ и, следовательно, распространить его по всей системе. Я вижу, что это происходит регулярно. Единственный способ быть уверенным в том, что ключ никогда не нужно будет менять, - это когда он по определению бессмысленен. Более того, современные базы данных очень эффективно обрабатывают внутренние соединения, поэтому потенциально большой выигрыш в пространстве от использования суррогатов обычно перевешивает преимущество отсутствия необходимости выполнять столько внутренних соединений.
@TTT: Тогда дизайн изначально был слабым. Опять же, именно здесь мужчины отделяются от мальчиков: они делают правильный выбор, когда использовать естественный ключ, а когда использовать суррогат. Вы решаете, что это для каждой таблицы, а не в качестве общей догмы.
@DanMan: Я бы сказал, что все люди действительно сделали правильный выбор, когда использовать естественные ключи, скажем, в 99,9% случаев. Это 1/1000 раз, когда мужчины сделали неправильный выбор, когда мальчикам приходилось приходить и убирать беспорядок.
"зачем вам это менять?" потому что PHB, который не знает, о чем они говорят, говорит, что HR необходимо заменить на Human Resources.
У меня также есть более чем 20-летний опыт работы, и я согласен с вашим мнением. Однажды я создал хранилище данных Oracle с суррогатными ключами, и обслуживание данных было адским. Вы просто никогда не сможете напрямую получить доступ к своим данным. вам всегда нужно писать запросы ко всему, и это делает суррогатные ключи просто ужасными в обращении.
Суррогатные ключи могут быть полезны, когда бизнес-информация может изменяться или быть идентичной. В конце концов, названия компаний не обязательно должны быть уникальными для страны. Предположим, вы имеете дело с двумя компаниями под названием Smith Electronics: одним в Канзасе и одним в Мичигане. Вы можете отличить их по адресу, но это изменится. Даже состояние может измениться; что, если Smith Electronics из Канзас-Сити, штат Канзас, перейдет через реку в Канзас-Сити, штат Миссури? Нет очевидного способа отделить эти предприятия с помощью естественной ключевой информации, поэтому суррогатный ключ очень полезен.
Думайте о суррогатном ключе как о номере ISBN. Обычно вы определяете книгу по названию и автору. Однако у меня есть две книги под названием «Перл-Харбор» Х. П. Уиллмотта, и это определенно разные книги, а не просто разные издания. В таком случае я мог бы сослаться на внешний вид книг, или более ранний по сравнению с более поздним, но это также хорошо, что у меня есть ISBN, на который можно опираться.
Думаю, я не могу согласиться с вашим примером здесь. Номер ISBN - это атрибут книги. Суррогатный ключ не зависит от остальных данных строки, поэтому в этой позиции рекомендуется использовать отдельный суррогатный ключ для таблицы книги, даже если ISBN уже однозначно идентифицирует каждую книгу.
В качестве альтернативы можно рассматривать ISBN как сам суррогатный ключ. Это не имеющий значения идентификатор, просто код, который применяется к конкретной книге. Если вы создаете таблицу с книгами, ISBN также может быть первичным ключом (при условии, что у вас есть и всегда будет по одной книге на строку).
@Christopher Cashell - наткнулся на этот пост год назад, но подумал добавить что-нибудь. Не гарантируется, что номера ISBN уникальны и могут иметь дубликаты. У меня есть друг, который проработал в библиотеке несколько лет, и ему часто попадались книги с повторяющимися номерами ISBN. Проблема в том, что уникальность ISBN лежит на издателе, а не на одном органе, который гарантирует, что все номера для всех публикаций уникальны, и эти издатели не всегда действовали сообща.
Наткнулся на этот пост год назад и хотел упомянуть, что ISBN на самом деле являются естественными ключами. В отличие от суррогатного ключа, в самом значении ключа есть смысл. Например, часть ключа идентифицирует издателя. Кроме того, как я упоминал выше, их уникальность не гарантируется. Они предполагаемый, чтобы быть уникальными, но эта уникальность исходит от издателей, и они не всегда были идеальными.
Технически корпорации не могут перемещаться между штатами; происходит то, что в новом государстве создается новая корпорация и передаются активы. Это работает и для информации из базы данных.
В случае базы данных на определенный момент времени лучше всего иметь комбинацию суррогатных и естественных ключей. например вам необходимо отслеживать информацию о членах клуба. Некоторые атрибуты члена никогда не меняются. например, Дата рождения, но имя может измениться. Итак, создайте таблицу Member с суррогатным ключом member_id и получите столбец для DOB. Создайте еще одну таблицу с именем person name и добавьте столбцы для member_id, member_fname, member_lname, date_updated. В этой таблице естественным ключом будет member_id + date_updated.
Я вообще ненавижу суррогатные ключи. Их следует использовать только тогда, когда нет качественного естественного ключа. Когда вы думаете об этом, довольно абсурдно думать, что добавление бессмысленных данных в вашу таблицу может улучшить ситуацию.
Вот мои причины:
При использовании естественных ключей таблицы группируются в соответствии с наиболее частым поиском, что ускоряет выполнение запросов.
При использовании суррогатных ключей необходимо добавить уникальные индексы в столбцы логических ключей. Вам по-прежнему необходимо предотвратить логическое дублирование данных. Например, вы не можете разрешить две организации с одинаковым именем в таблице организации, даже если pk является столбцом суррогатного идентификатора.
Когда суррогатные ключи используются в качестве первичного ключа, гораздо менее ясно, что такое естественные первичные ключи. При разработке вы хотите знать, какой набор столбцов делает таблицу уникальной.
В цепочках отношений от одного до многих - логические цепочки ключей. Так, например, в организациях много учетных записей, а в учетных записях много счетов-фактур. Таким образом, логическим ключом организации является OrgName. Логический ключ учетных записей - OrgName, AccountID. Логическим ключом счета-фактуры является OrgName, AccountID, InvoiceNumber.
Когда используются суррогатные ключи, цепочки ключей усекаются только за счет наличия внешнего ключа для непосредственного родителя. Например, в таблице «Счет-фактура» нет столбца OrgName. В нем есть только столбец для AccountID. Если вы хотите найти счета-фактуры для данной организации, вам нужно будет присоединиться к таблицам «Организация», «Учетная запись» и «Счет-фактура». Если вы используете логические ключи, вы можете напрямую запросить таблицу организации.
Сохранение значений суррогатных ключей в таблицах поиска приводит к тому, что таблицы заполняются бессмысленными целыми числами. Для просмотра данных необходимо создать сложные представления, которые присоединяются ко всем таблицам поиска. Таблица поиска предназначена для хранения набора допустимых значений для столбца. Его не следует кодифицировать, сохраняя вместо этого целочисленный суррогатный ключ. В правилах нормализации нет ничего, что предлагало бы хранить суррогатное целое число вместо самого значения.
У меня есть три разные книги по базам данных. Ни один из них не показывает использование суррогатных ключей.
Я ненавижу суррогатные ключи, кроме случаев, когда они необходимы. Они необходимы, когда предприятие использует естественный ключ, который подвержен множеству ошибок, и не желает терпеть базу данных, на которую влияют эти ошибки.
-1: Я написал и поддержал десятки приложений. Больше всего проблем с данными испытывали те, у кого использовались естественные ключи.
№6 - на самом деле довольно веский аргумент. Хотя я могу быть предвзятым, потому что мне не нравятся суррогатные ключи :)
Добавление к 3 .: другими словами, вы сразу узнаете, какие поля обязательны в пользовательской форме, чтобы иметь возможность создать еще одну строку в таблице.
Некоторые из ваших точек зрения предполагают, что суррогатный ключ должен быть PK или должен быть кластеризованным столбцом - это не так. Ваши пункты 1 и 5 игнорируют тот факт, что целые числа составляют 4 байта, а естественные ключи почти всегда много, намного больше байтов. И каждый некластеризованный индекс должен повторять байты тех естественных ключей, которые находятся в кластеризованном индексе, поэтому таблицы и индексы в вашей базе данных естественных ключей будут иметь гораздо, гораздо меньше строк на страницу, что приводит к производительности чтения намного хуже, что делает запросы помедленнее, а не быстрее.
Еще одна причина против естественных ключей (примеры: атомные номера, VIN и т. д.), Бизнес-логика может измениться, что увеличивает тип данных. Например - До: отслеживание зарядов атомов, После: отслеживание зарядов атомов и соединений. До: Отслеживание транспортных средств на предмет грузоподъемности. После: добавление самолетов, лодок, велосипедов и людей для определения грузоподъемности.
Я думаю, у вас нет таблиц, в которых первичный ключ хотя бы частично состоит из 1) любого атрибута, который может и будет изменяться) или 2) из пользовательского ввода (например, динамически сгенерированных списков поиска). Если вы не можете гарантировать неизменность ключа, вам придется обновить все эти отношения сущностей с помощью кода или ручных сценариев «исправления». Если вам никогда не приходилось этого делать ... Я полагаю, ваша база данных является и суррогатной без ключа, и ... необычной.
@Falcon, не могли бы вы рассказать больше о «[приложениях] с наибольшим количеством проблем, связанных с данными, были те, которые использовали естественные ключи»? Например, почему возникли проблемы с данными? Какие проблемы? Как использование суррогатного ключа решит эти проблемы?
@Dennis - Для меня было много случаев, когда мне приходилось изменять одно из значений NK из-за ошибки или деловой необходимости. Если бы я использовал схему использования NK в качестве PK (без суррогата), мне пришлось бы удалить и вставить соответствующую строку. Само по себе это не звучит ужасно, за исключением случаев, когда это FK другой таблицы. Обработка этого ключевого каскада (и его правильное выполнение) может быстро превратиться в кошмар. С суррогатным ключом мне нужно только одно обновление.
Причина № 6 - логическая ошибка. Просто потому, что этого нет в книге, это не значит, что это неверно или неверно. Следование этой логике приводит к каждой идее, о которой не было написано в книге, прежде чем она была задумана или замечена в другом месте как неправильная или ложная.
Лошадь для курсов. Чтобы заявить о моей предвзятости; Я в первую очередь разработчик, поэтому меня в основном беспокоит предоставление пользователям работающего приложения.
Я работал над системами с естественными ключами, и мне пришлось потратить много времени, чтобы убедиться, что изменения значений будут происходить непрерывно.
Я работал с системами только с суррогатными ключами, и единственным недостатком было отсутствие денормализованных данных для разделения.
Большинство традиционных разработчиков PL / SQL, с которыми я работал, не любили суррогатные ключи из-за количества таблиц на соединение, но наши тестовые и производственные базы данных никогда не вызывали беспокойства; дополнительные соединения не повлияли на производительность приложения. С диалектами базы данных, которые не поддерживают такие предложения, как «внутреннее соединение X Y на Xa = Yb», или разработчиками, которые не используют этот синтаксис, дополнительные соединения для суррогатных ключей действительно затрудняют чтение запросов, их более длительный ввод и проверьте: см. сообщение @Tony Andrews. Но если вы используете ORM или любой другой фреймворк для генерации SQL, вы этого не заметите. Слепой набор также смягчает.
Также; если вы действительно хотите убедить вас, что суррогатные ключи - это всего лишь таковые, начните их со случайного большого числа и увеличивайте последовательности на 3+, а не на 1. Или используйте ту же последовательность для генерации значений для более чем одного ключа.
Напоминаем, что не рекомендуется размещать кластеризованные индексы на случайных суррогатных ключах, то есть идентификаторах GUID, которые читают XY8D7-DFD8S, поскольку SQL Server не имеет возможности физически сортировать эти данные. Вместо этого вам следует разместить уникальные индексы для этих данных, хотя может быть также полезно просто запустить профилировщик SQL для основных операций с таблицами, а затем поместить эти данные в помощник по настройке ядра СУБД.
См. Ветку @ http://social.msdn.microsoft.com/Forums/en-us/sqlgetstarted/thread/27bd9c77-ec31-44f1-ab7f-bd2cb13129be
Я почти уверен, что SQL Server может сортирует GUID.
Это неточно, хотя они могут оценить GUID, полученная сортировка не является бессмысленной для человека. stackoverflow.com/questions/7810602/…
Верное утверждение, но совершенно иное, чем «SQL Server не имеет возможности физически отсортировать их».
Случай 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 о дилемме естественных и суррогатных ключей. Я думаю, что суррогатные ключи обе (искусственно созданные автоматически) и естественные ключи (состоящие из столбцов со значением домена) имеют плюсы и минусы. Поэтому, в зависимости от вашей ситуации, может быть более уместным выбрать тот или иной метод.
Поскольку кажется, что многие люди представляют суррогатные ключи как почти идеальное решение, а естественные ключи - как чуму, я сосредоточусь на аргументах другой точки зрения:
Суррогатные ключи:
Используйте естественные ключи, когда это необходимо, и используйте суррогатные ключи, когда их лучше использовать.
Надеюсь, что это кому-то помогло!
Что происходит, когда дата вылета обычного рейса переносится? Вам нужно отслеживать все связанные объекты и удалять ключи, или вы действительно обновляете все ключи в связанных объектах? Или вы имеете дело с простой, единственной таблицей (возможно, даже не с 3NF)?
Отличный момент @ code4life
@ code4life: Вот здесь и появляется операционный суффикс. Чтобы сохранить тот же номер рейса и избежать путаницы с клиентом, мы добавляем только суффикс (например, «D»).
«У вас всегда может быть 2 строки со всеми одинаковыми значениями столбцов, но с другим сгенерированным значением», поэтому просто установите уникальное или составное уникальное ограничение на свои столбцы.
Зачем иметь первичный индекс для автоматически сгенерированного значения И уникальный индекс для естественного ключа, если вы можете сохранить только один?
@Joachim Sauer: Спор о том, является ли вещь субъективной, может быть сам по себе субъективным, без какого-либо отношения к объективности или субъективности рассматриваемой вещи. Если вы не готовы указать точные объективные критерии, которые делают что-то объективным. Есть вещи, которые называются «открытыми понятиями», например, сколько волосков нужно, чтобы сделать бороду. Можно объективно сказать, что у человека без волос на подбородке нет бороды, а у человека с 5 000 волос на дюйм в длину есть борода, но где-то посередине требуется субъективное суждение, чтобы сделать объективное определение.