Должна ли каждая таблица иметь первичный ключ?


341

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

Должна ли каждая таблица иметь первичный ключ?


5
Не могли бы вы дать более подробную информацию о столе? Ответ, вероятно, "да", хотя.
— Райан Бэйр

7
Да, каждая таблица должна иметь первичный ключ.
— Сайед Тайяб Али

Ответы:


314

Краткий ответ: да .

Длинный ответ:

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

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

Обратите внимание, что первичный ключ может быть составным.

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

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

А поскольку любой первичный ключ включает создание уникального индекса, вы должны объявить его и получить как логическую согласованность, так и производительность.

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

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

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


у них все еще есть первичный ключ, составной
— kristof

2
@annakata: у них должен быть составной первичный ключ
— Quassnoi

1
«А поскольку любой PRIMARY KEY предполагает создание УНИКАЛЬНОГО индекса», это неверно для Oracle. Можно использовать неуникальный индекс для обеспечения первичного ключа. Фактически иногда ТРЕБУЕТСЯ, чтобы ограничения уникальности и PK использовали неуникальные индексы.
— Стефани Пейдж

3
Просто комментарий к риторическому вопросу «Зачем вести одинаковые записи?». Обратите внимание, что простое добавление PK не гарантирует отсутствие дублирования. Часто PK не виден пользователю, поэтому важно то, что находится в видимых полях, которые могут содержать дублирующиеся данные. В зависимости от вашего дизайна это может быть желательно или нет.
— Росско

1
Ключи не имеют ничего общего с присоединяемостью. И аргумент кластеризации зависит от того, какую СУБД вы используете, и сочетает логические и физические соображения.
— Джон Хеггланд

36

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

Как утверждают другие, есть некоторые причины не иметь первичный ключ, но большинство не пострадает, если есть первичный ключ


5
@PaulSuart Данные не всегда должны быть в их нормальном виде. Фактически, когда данные становятся огромными, их не следует хранить в их обычной форме, иначе доступ к данным будет ужасно медленным для запросов, выполняющих объединения таблиц и т. Д. Нормальные формы - это «идеализация» и практически возможны только тогда, когда данные не будут расти огромно.
— Pacerier

13

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


13
Таблица соединений - это первичный ключ - составной, состоящий из PK обеих записей, которые объединяются. Например, CREATE TABLE PersonOrder (PersonId int, OrderId int, ПЕРВИЧНЫЙ КЛЮЧ (PersonId, OrderId)).
— Кит Уильямс

3
Да, но что если таблица ссылок имеет также третий атрибут, скажем, «OrderDate». Вы бы добавили это и в составной ключ? ИМХО нет - потому что он еще более сводим и не служит неприводимым признаком, который должен иметь первичный ключ.
— Stevek

13

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

Если у него нет первичного ключа, это не таблица!

Марк


10
Строго говоря, это предложение неверно. Таблицы могут быть «Просмотреть таблицы», созданные вашим языком запросов. СУБД состоит из отношений, а не таблиц. В этом предложении должно быть сказано: «Если у него нет первичного ключа, это не отношение!».
— Stevek

Или, возможно, «если нет ключей-кандидатов, то это не реляционная таблица». Но посмотрите на очень редкие случаи, когда нормально иметь таблицу, которая не представляет отношения.
— Уолтер Митти

Почему таблица «многие ко многим» не имеет первичного ключа? Вы можете создать отдельный первичный ключ, а затем создать уникальный индекс для суррогата внешних ключей. Я думаю, что лучше иметь первичный ключ на каждом столе. Даже в таблице массовой загрузки может потребоваться отдельно определить первичный ключ, который не включает импортируемые данные, поскольку он может помочь вам идентифицировать дубликаты записей в процессе ETL. Мне кажется, что у каждой таблицы должен быть первичный ключ, даже если он немного больше памяти. Таблица, созданная представлением, является подмножеством таблицы, а не самой таблицей.
— Джон Эрнест

1
В таблице отношений «многие ко многим» вы можете создать составной первичный ключ, состоящий из обоих идентификаторов отношений.
— Яап

8

Просто добавьте его, вы будете сожалеть позже, когда вы этого не сделали (выбор, удаление. Ссылки и т. Д.)


8

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

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

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


6

Рекомендуется иметь ПК на каждом столе, но это НЕ ДОЛЖНО. Скорее всего, вам понадобится уникальный индекс и / или кластерный индекс (который является PK или нет) в зависимости от ваших потребностей.

Ознакомьтесь с разделами «Основные ключи» и «Кластерные индексы» в электронной документации (для SQL Server)

« Ограничения PRIMARY KEY идентифицируют столбец или набор столбцов, которые имеют значения, которые однозначно идентифицируют строку в таблице. Никакие две строки в таблице не могут иметь одинаковое значение первичного ключа. Вы не можете ввести NULL для любого столбца в первичном ключе. Мы Рекомендуется использовать небольшой целочисленный столбец в качестве первичного ключа. Каждая таблица должна иметь первичный ключ. Столбец или комбинация столбцов, которые квалифицируются как значение первичного ключа, упоминаются как ключ-кандидат. "

Но затем проверьте это также: http://www.aisintl.com/case/primary_and_foreign_key.html


1
Проверьте это также, sql-server-performance.com/2006/primary-key-index-clustered
— endo64

4
эта страница довольно глупая. Во-первых, первичный ключ необходим для повышения производительности. Читая его страницу, я узнаю, что добавление идентификатора в таблицу книг бесполезно, поскольку текст книги уникален; очевидно, парень никогда не работал с базами данных. Но у него также есть проблемы в понимании того, что он критикует. На странице написано, что 1) значение PK ссылается на строку 2) вы можете объединить 2 таблицы по любому набору столбцов. Противоречия нет. Удивительно, что автор академической статьи не понимает основы теории отношений.
— Федерико Раззоли,

1
«Во-первых, первичный ключ необходим для повышения производительности», это неверно, PK не влияет напрямую на производительность. Отсутствие PK может привести к множеству проблем (определение строки, присоединение и т. Д.), Но производительность не является одной из них. Когда вы создаете PK на таблице, SQL-сервер создает уникальный кластеризованный индекс, этот индекс влияет на производительность, а не на сам PK. В качестве реального примера моя таблица имеет кластерный индекс по столбцу даты и PK в поле GUID, потому что мои строки должны быть физически упорядочены по столбцу даты в таблице, поскольку все запросы имеют диапазон дат (в моем случае).
— endo64

Этот кластерный индекс является разновидностью первичного ключа, созданного SQL Server и несколькими другими СУБД. Вы уверены, что это хорошая идея? Например, в MySQL это не по нескольким недокументированным причинам.
— Федерико Раззоли

1
Имейте в виду, что GUID не является оптимальным типом для PK в InnoDB. Все индексы содержат ссылку на PK, поэтому чем больше PK, тем больше будут все остальные индексы.
— Федерико Раззоли

6

Не согласен с предложенным ответом. Короткий ответ: НЕТ .

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

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

Небольшой пример: Таблица A: LogData

Columns:  DateAndTime, UserId, AttribA, AttribB, AttribC etc...

Первичный ключ не требуется.

Таблица B: Пользователь

Columns: Id, FirstName, LastName etc. 

Первичный ключ (Id) необходим для использования в качестве «внешнего ключа» для таблицы LogData.


3

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


3

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


Я еще не уверен, что это необходимо, но «сделайте это, потому что в противном случае кому-то придется столкнуться с последствиями позже», этого достаточно, чтобы заставить меня ошибиться. Я всегда могу просто опустить столбец позже, если кажется, что стоит попытаться уменьшить его ...
— ArtOfWarfare

3

Я нахожусь в роли поддержки приложения, созданного оффшорной командой разработчиков. Теперь у меня возникают всевозможные проблемы в приложении, потому что исходная схема базы данных не содержала ПЕРВИЧНЫЕ КЛЮЧИ в некоторых таблицах. Поэтому, пожалуйста, не позволяйте другим людям страдать из-за вашего плохого дизайна. Всегда полезно иметь первичные ключи на таблицах.


2

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


1

Короче нет. Однако необходимо помнить, что некоторые операции CRUD для клиентского доступа требуют этого. Для проверки будущего я обычно использую первичные ключи.


1

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.