2008-10-03 3 views
17

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

Предположим, что определенная таблица имеет поле «Имя», для которого никакие две строки не будут иметь одинаковое значение. Тем не менее, пользователи смогут изменить поле «Имя» в любое время.

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

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

+0

Общепринятое исключение для данных «системы». т.е. материал, который вы определяете сами поля статуса и т. д. – ShoeLace 2008-10-03 13:21:09

ответ

25

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

+2

Это, как правило, принятый способ обработки первичных ключей. Вы никогда не должны выбирать столбец для вашего первичного ключа, где его значение может быть изменено, так как вы затем получаете каскадное обновление для всех таблиц с помощью этого ключа. – 2008-10-03 13:18:11

0

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

2

Да - и как правило, всегда, для каждой таблицы.

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

Это базовая хорошая практика для схем db.

2

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

Он также позволит вам в будущем вносить изменения в базу данных. Довольно часто у вас есть уникальный столбец имен, чтобы узнать позже, что имя оно не уникально вообще.

Прямо сейчас, вы можете обеспечить уникальность столбца . Имя, указав на нем индекс.

2

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

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

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

10

То, что вы описываете, называется ключом суррогатного ключа.Подробный ответ см. На Wikipedia article.

1

Если вы живете в разреженных кругах теоретических математиков (например, C. Date in the-land-where-there-are-no-nulls, потому что все значения данных известны и правильны), то первичные ключи могут быть построены из компонентов данных, которые идентифицируют идеализированный платоновский объект, к которому вы обращаетесь (например, имя + день рождения + место рождения + имена родителей), но в беспорядочном реальном мире «синтетические ключи», которые могут идентифицировать ваш реальный, мировые сущности в контексте вашей базы данных - гораздо более практичный способ сделать что-то. (И поля с нулевыми значениями могут быть очень полезны.)

+0

Будем надеяться, что Celko никогда не станет Штабелером, или мы все хотим стать крупным одеванием. – 2008-10-03 13:40:43

+0

О, мы все будем плохо, когда это произойдет! – 2008-10-03 16:46:55

1

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

Единственное место, где работают натуральные ключи, находится в таблице кодов, например, таблица, отображающая значение статуса для его описания. Не имеет смысла давать «Активный» первичный ключ 1, «Задержка» первичный ключ 2 и т. Д. Когда так же легко дать «Актив» первичный ключ «ACT»; «Задержка», «DLY»; «В ожидании», «HLD» и т. Д.

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

+0

Другой пример: `country_code` (` US`, `UK` и т. Д.). Люди склонны использовать 4-байтовый `INT`, когда` CHAR (2) CHARACTER SET ascii` занимает всего 2 байта и работает лучше по другим причинам. Когда Чехословакия разделилась на Чехию и Словакию, вам придется писать код для дизайна первичного ключа. – 2017-06-08 23:21:53

6

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

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

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

1

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

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

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

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

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

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

0

В дополнение к тому, что все сказано, рассмотрите с использованием UUID как ПК. Это позволит вам создавать ключи, которые uniq охватывают несколько баз данных.

Если вам когда-либо понадобится экспортировать/объединить данные с другой базой данных, данные всегда будут оставаться уникальными, а отношения могут быть легко сохранены.

Смежные вопросы