При разработке таблиц я выработал привычку иметь один столбец, который является уникальным и который я делаю первичным ключом. Это достигается тремя способами в зависимости от требований:
- Целочисленный столбец идентификаторов, который автоматически увеличивается.
- Уникальный идентификатор (GUID)
- Столбец с коротким символом (x) или целым числом (или другим относительно небольшим числовым типом), который может служить столбцом идентификатора строки
Номер 3 будет использоваться для довольно небольшого поиска, в основном для чтения таблиц, которые могут иметь уникальный строковый код статической длины или числовое значение, например год или другое число.
По большей части все другие таблицы будут иметь либо автоинкрементное целое число, либо первичный ключ уникального идентификатора.
Вопрос :-)
Недавно я начал работать с базами данных, которые не имеют согласованного идентификатора строки, и первичные ключи в настоящее время сгруппированы по различным столбцам. Некоторые примеры:
- Дата и время / характер
- Дата и время / число
- Дата и время / VARCHAR
- символ / NVARCHAR / NVARCHAR
Есть ли веские аргументы для этого? Я бы всегда определял столбец идентификаторов или уникальных идентификаторов для этих случаев.
Кроме того, существует множество таблиц без первичных ключей. Каковы веские причины для этого?
Я пытаюсь понять, почему таблицы были спроектированы такими, какими они были, и для меня это кажется большим беспорядком, но, возможно, для этого были веские причины.
Третий вопрос, помогающий мне расшифровать ответы: в тех случаях, когда для составного первичного ключа используются несколько столбцов, есть ли конкретное преимущество этого метода по сравнению с суррогатным / искусственным ключом? Я думаю в основном о производительности, обслуживании, администрировании и т. Д.?
источник
Ответы:
Я следую нескольким правилам:
На суррогатном против естественного ключа, я ссылаюсь на правила выше. Если естественный ключ мал и никогда не изменится, его можно использовать в качестве первичного ключа. Если натуральный ключ большой или может измениться, я использую суррогатные ключи. Если первичного ключа нет, я все равно создаю суррогатный ключ, потому что опыт показывает, что вы всегда будете добавлять таблицы в свою схему и хотели бы, чтобы на месте был первичный ключ.
источник
Int
sПриродные стихи искусственных ключей - это своего рода религиозные дебаты в сообществе баз данных - см. Эту статью и другие, на которые она ссылается. Я не за то, чтобы всегда иметь искусственные ключи или никогда не иметь их. Я бы решил в каждом конкретном случае, например:
Везде, где используются искусственные ключи, вы всегда должны объявлять уникальные ограничения на естественные ключи. Например, используйте state_id, если необходимо, но тогда вам лучше объявить уникальное ограничение на код_состояния, в противном случае вы обязательно в конечном итоге получите:
источник
Просто дополнительный комментарий к чему-то, что часто упускается из виду. Иногда не использование суррогатного ключа имеет преимущества в дочерних таблицах. Допустим, у нас есть дизайн, который позволяет вам управлять несколькими компаниями в одной базе данных (может быть, это размещенное решение или что-то в этом роде).
Допустим, у нас есть эти таблицы и столбцы:
Если последний бит не имеет смысла, он
Invoice.CompanyId
является частью двух внешних ключей, одного для таблицы CostCentre и одного для таблицы CostElement . Первичный ключ ( InvoiceId , CompanyId ).В этой модели невозможно испортить и ссылаться на CostElement от одной компании и CostCentre от другой компании. Если суррогатный ключ использовался в таблицах CostElement и CostCentre , он был бы.
Чем меньше шансов облажаться, тем лучше.
источник
Я избегаю использовать естественные ключи по одной простой причине - человеческая ошибка. Хотя естественные уникальные идентификаторы часто доступны (SSN, VIN, номер счета и т. Д.), Они требуют, чтобы человек вводил их правильно. Если вы используете SSN в качестве первичного ключа, кто-то транспонирует пару цифр во время ввода данных, и ошибка не обнаруживается сразу, тогда вы сталкиваетесь с изменением вашего первичного ключа.
Все мои первичные ключи обрабатываются программой базы данных в фоновом режиме, и пользователь никогда не узнает о них.
источник
Нет проблем в создании первичного ключа из различных областей, это естественный ключ .
Вы можете использовать столбец Identity (связанный с уникальным индексом на полях-кандидатах), чтобы создать суррогатный ключ .
Это старая дискуссия. Я предпочитаю суррогатные ключи в большинстве ситуаций.
Но нет оправдания отсутствию ключа.
RE: РЕДАКТИРОВАТЬ
Да, есть много споров по этому поводу: D
Я не вижу очевидного преимущества в натуральных ключах, кроме того, что они являются естественным выбором. Вы всегда будете думать в Имя, SocialNumber - или что-то в этом роде - вместо idPerson .
Суррогатные ключи являются ответом на некоторые проблемы, которые возникают у естественных ключей (например, распространение изменений).
Когда вы привыкаете к суррогатам, это кажется более чистым и управляемым.
Но, в конце концов, вы обнаружите, что это просто вопрос вкуса или мышления. Люди «лучше думают» с помощью естественных ключей, а другие нет.
источник
Таблицы должны иметь первичный ключ все время. Когда это не так, это должны были быть поля AutoIncrement.
Иногда люди пропускают первичный ключ, потому что они передают много данных, и это может замедлить (зависит от базы данных) процесс. НО, это должно быть добавлено после этого.
Несколько комментариев о таблице ссылок , это правильно, это исключение, НО поля должны быть FK для сохранения целостности, и в некоторых случаях эти поля также могут быть первичными ключами, если дублирование в ссылках не разрешено ... но хранить в простая форма, потому что в программировании часто встречаются исключения, должен присутствовать первичный ключ для сохранения целостности ваших данных.
источник
Помимо всех этих хороших ответов, я просто хочу поделиться хорошей статьей, которую я только что прочитал, Великие дебаты по первичным ключам .
Просто процитирую несколько пунктов:
Разработчик должен применить несколько правил при выборе первичного ключа для каждой таблицы:
Естественные ключи (как правило) нарушают правила. Суррогатные ключи соответствуют правилам. (Вам лучше прочитать эту статью, она стоит вашего времени!)
источник
Что особенного в первичном ключе?
Какова цель таблицы в схеме? Какова цель ключа таблицы? Что особенного в первичном ключе? Обсуждения вокруг первичных ключей, похоже, упускают из виду тот факт, что первичный ключ является частью таблицы, а эта таблица является частью схемы. То, что лучше для таблицы и отношений таблицы, должно определять ключ, который используется.
Таблицы (и связи таблиц) содержат факты об информации, которую вы хотите записать. Эти факты должны быть самодостаточными, значимыми, понятными и не противоречивыми. С точки зрения дизайна, другие таблицы, добавленные или удаленные из схемы, не должны влиять на данную таблицу. Должна быть цель для хранения данных, связанных только с самой информацией. Понимание того, что хранится в таблице, не требует проведения научно-исследовательского проекта. Ни один факт, хранящийся для одной и той же цели, не должен храниться более одного раза. Ключи представляют собой целую или часть записываемой информации, которая является уникальной, а первичный ключ - это специально назначенный ключ, который должен быть основной точкой доступа к таблице (т. Е. Его следует выбирать для согласованности и использования данных, а не просто для вставки). производительность).
Было сказано, что первичные ключи должны быть настолько маленькими, насколько это необходимо. Я бы сказал, что ключи должны быть настолько большими, насколько это необходимо. Следует избегать случайного добавления бессмысленных полей в таблицу. Еще хуже сделать ключ из случайно добавленного бессмысленного поля, особенно когда оно разрушает зависимость соединения от другой таблицы к неосновному ключу. Это разумно только в том случае, если в таблице нет хороших ключей-кандидатов, но это, безусловно, признак плохой схемы, если она используется для всех таблиц.
Также было сказано, что первичные ключи никогда не должны изменяться, поскольку обновление первичного ключа всегда должно быть исключено. Но обновление аналогично удалению с последующей вставкой. По этой логике вы никогда не должны удалять запись из таблицы с одним ключом, а затем добавлять другую запись со вторым ключом. Добавление суррогатного первичного ключа не устраняет тот факт, что другой ключ в таблице существует. Обновление не первичного ключа таблицы может разрушить значение данных, если другие таблицы имеют зависимость от этого значения через суррогатный ключ (например, таблица состояния с суррогатным ключом, описание состояния которого изменено с «Обработано» на «Отменено»). определенно испортил бы данные). То, что всегда должно быть исключено, это уничтожение значения данных.
Сказав это, я благодарен за многие плохо спроектированные базы данных, которые существуют сегодня на предприятиях (бессмысленные-суррогатные ключи-данные-повреждены-1NF), потому что это означает, что существует бесконечный объем работы для людей, которые понимают правильное проектирование баз данных. , Но с грустной стороны, это иногда заставляет меня чувствовать себя как Сизиф, но я держу пари, что у него был один черт 401k (до крушения). Держитесь подальше от блогов и веб-сайтов для важных вопросов дизайна базы данных. Если вы разрабатываете базы данных, посмотрите CJ Date. Вы также можете ссылаться на Celko для SQL Server, но только если сначала будете держать себя за нос. На стороне Oracle, ссылка Том Кайт.
источник
Естественный ключ, если таковой имеется, обычно лучше. Итак, если datetime / char однозначно идентифицирует строку и обе части имеют значение для строки, это здорово.
Если значение имеет только дата и время, а символ просто привязан, чтобы сделать его уникальным, то вы могли бы просто пойти с полем идентификации.
источник
Вот мое собственное правило, на котором я остановился после 25 лет опыта разработки.
Первичный ключ используется базой данных в целях оптимизации и не должен использоваться вашим приложением ни для чего иного, кроме идентификации конкретной сущности или ее связи с конкретной сущностью.
Постоянное использование первичного ключа с одним значением делает выполнение операций UPSERT очень простым.
Используйте дополнительные индексы для поддержки ключей из нескольких столбцов, которые имеют значение в вашем приложении.
источник
Естественные и искусственные ключи для меня - это вопрос того, сколько бизнес-логики вы хотите в своей базе данных. Номер социального страхования (SSN) является отличным примером.
«Каждый клиент в моей базе данных будет и должен иметь SSN». Бам, готово, сделай его первичным ключом и покончим с этим. Просто помните, когда ваше бизнес-правило меняется, вы сожжены.
Я сам не люблю натуральные ключи из-за своего опыта в изменении бизнес-правил. Но если вы уверены, что это не изменится, это может предотвратить несколько критических соединений.
источник
Я подозреваю, что свернутая газетная терапия Стивена А. Лоу требуется для дизайнера исходной структуры данных.
Кроме того, GUID в качестве первичного ключа может привести к снижению производительности. Я бы не рекомендовал это.
источник
Вы должны использовать «составной» или «составной» первичный ключ, который состоит из нескольких полей.
Это вполне приемлемое решение, иди сюда для получения дополнительной информации :)
источник
Я тоже всегда использую числовой идентификатор столбца. В оракуле я использую число (18,0) без реальной причины выше числа (12,0) (или что-то большее, чем целое, а не длинное), возможно, я просто не хочу беспокоиться о получении нескольких миллиардов строк в дБ!
Я также включил созданный и измененный столбец (отметка времени) для базового отслеживания, где это кажется полезным.
Я не против установки уникальных ограничений на другие комбинации столбцов, но мне действительно нравится мой идентификатор, созданные, измененные базовые требования.
источник
Я ищу естественные первичные ключи и использую их, где могу.
Если естественные ключи не могут быть найдены, я предпочитаю GUID для INT ++, потому что SQL Server использует деревья, и плохо всегда добавлять ключи к концу в деревьях.
В таблицах со многими связями я использую составной первичный ключ внешних ключей.
Поскольку мне посчастливилось использовать SQL Server, я могу изучить планы выполнения и статистику с помощью профилировщика и анализатора запросов и выяснить, как мои ключи работают очень легко.
источник
Я всегда использую поле номера или идентификатора.
Я работал на клиента, который использовал SSN в качестве первичного ключа, а затем из-за правил HIPAA был вынужден изменить его на «MemberID», и это вызвало массу проблем при обновлении внешних ключей в связанных таблицах. Придерживаясь последовательного стандарта столбца идентификации, я избежал подобной проблемы во всех моих проектах.
источник
Все таблицы должны иметь первичный ключ. В противном случае у вас есть HEAP - в некоторых ситуациях это может быть тем, что вам нужно (например, интенсивная загрузка вставки, когда данные затем реплицируются через сервисный брокер в другую базу данных или таблицу).
Для справочных таблиц с небольшим объемом строк вы можете использовать код 3 CHAR в качестве первичного ключа, поскольку он занимает меньше места, чем INT, но разница в производительности незначительна. Кроме этого, я всегда использовал бы INT, если у вас нет справочной таблицы, которая, возможно, имеет составной первичный ключ, составленный из внешних ключей из связанных таблиц.
источник
Если вы действительно хотите прочитать все эти и другие споры об этих давних дебатах, выполните поиск «естественного ключа» в переполнении стека. Вы должны получить обратно страницы результатов.
источник
Идентификаторы GUID можно использовать в качестве первичного ключа, но вам нужно создать правильный тип GUID, чтобы он работал хорошо.
Вам нужно создать COMID GUID. Хорошая статья об этом и статистике производительности - Стоимость GUID как первичных ключей. .
Также некоторый код для создания COMID GUID в SQL находится в Uniqueidentifier vs identity ( архив ) .
источник
Мы выполняем много объединений, и составные первичные ключи просто стали причиной снижения производительности. Простое int или long решает многие проблемы, даже если вы вводите второй ключ-кандидат, но гораздо проще и понятнее объединиться в одной области, чем в трех.
источник
Я буду честен о своем предпочтении натуральных ключей - используйте их, где это возможно, так как они значительно облегчат вам жизнь в администрировании баз данных. Я установил стандарт в нашей компании, что все таблицы имеют следующие столбцы:
SUSER_SNAME()
в T-SQL))У идентификатора строки есть уникальный ключ для каждой таблицы, и в любом случае он генерируется автоматически для каждой строки (а разрешения запрещают его редактирование), и гарантированно будет уникальным для всех таблиц и баз данных. Если какой-либо системе ORM требуется один ключ ID, это тот, который нужно использовать.
Между тем, фактический PK является, если возможно, естественным ключом. Мои внутренние правила примерно такие:
EventId, AttendeeId
)Таким образом, в идеале вы получите естественный, понятный для человека и запоминающийся PK, а также ORM-удобный GUID «один идентификатор на таблицу».
Предостережение: базы данных, которые я поддерживаю, имеют тенденцию к сотням тысяч записей, а не миллионам или миллиардам, поэтому, если у вас есть опыт работы с большими системами, который противоречит моему совету, смело игнорируйте меня!
источник
GUID
иINT
SK для таблиц без строгого естественного ключа?