2008-10-01 2 views
44

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

Я прочитал много статей/дискуссий/сообщений в группах, в которых говорилось, что лучше использовать уникальное ограничение (также уникальный индекс для некоторого db) вместо PK.

Какова у вас точка зрения?

ответ

38

Можете ли вы предоставить ссылки на эти статьи?

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

Использование UNIQUE для обслуживания той же цели звучит по-настоящему хакерски для меня. Каково их обоснование?

Редактировать: мое внимание только что привлекло этот старый ответ. Возможно, дискуссия, которую вы прочитали относительно ПК против UNIQUE, касалась людей, делающих что-то ПК исключительно с целью обеспечения уникальности на нем. Ответ на это: если это ключ, тогда сделайте его ключом, иначе сделайте его УНИКАЛЬНЫМ.

+1

Вы говорите, если это ключ, сделайте его ключом, если он уникален, сделайте его уникальным. Но на самом деле, что делает ключ ключевым и не уникальным? Каково ваше определение ключа * *? – Pacerier 2013-11-22 21:38:04

+0

@Pacerier Предположим, у нас есть база данных для студентов. В этой базе данных ученики идентифицируются с основным номером студента. В таблице для студентов мы храним такие вещи, как SSN/SIN или другой региональный эквивалент. В рамках проверки ошибок при наборе ключей мы хотим, чтобы это поле было уникальным. Но это не ключевое поле. (Хотя это может быть, предполагая соответствие 1: 1 между StuID и SSN) Назначение номеров также может быть уникальным, но не ключевым. (Хотя я был бы более склонным назначать ученика в комнату, чем комнату для ученика) – 2013-11-28 13:48:21

+0

В вашем примере почему бы не сделать SSN/SIN ключом? – Pacerier 2013-11-30 03:52:44

9

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

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

Правило всегда иметь ПК хорошее.

http://msdn.microsoft.com/en-us/library/ms191166.aspx

3

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

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

1

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

ПЕРСОНАЛЬНО Я использую либо GUID, либо автоматически увеличивая BIGINTS (Identity Insert для SQL SERVER) для уникальных ключей, используемых для перекрестных ссылок среди моих таблиц. Затем я буду использовать другие данные, чтобы пользователь мог выбирать определенные записи.

Например, у меня будет список сотрудников и с GUID привязан к каждой записи, которую я использую за кулисами, но когда пользователь выбирает сотрудника, они выбирают их на основе следующих полей : LastName + FirstName + EmployeeNumber.

Мой первичный ключ в этом сценарии - LastName + FirstName + EmployeeNumber, а уникальным ключом является связанный GUID.

10

Первичный ключ - это только ключ-кандидат (уникальное ограничение), выделенное для специального лечения (автоматическое создание индексов и т. Д.).

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

[Изменить] По-видимому, я не могу комментировать даже на свой собственный ответ без 50 баллов.

@chris: Я не думаю, что есть какой-либо вред. «Первичный ключ» - это действительно просто синтаксический сахар. Я использую их все время, но я, конечно, не думаю, что они требуются. Требуется уникальный ключ , да, но необязательно Первичный ключ.

0

Если вы планируете использовать LINQ-to-SQL, ваши таблицы потребуют Первичные ключи, если вы планируете выполнять обновления, и для них потребуется столбец timestamp, если вы планируете работать в отключенной среде (например, передавать объект через приложение службы WCF).

Если вам нравятся .NET, PK's и FK являются вашими друзьями.

46

Первичный ключ на самом деле просто candidate key, который не допускает NULL. Таким образом, в терминах SQL - это ничем не отличается от любого другого уникального ключа.

Однако для наших нетеоретических РСУБД у вас должен быть первичный ключ - я никогда не слышал, чтобы он утверждал иначе. Если этот первичный ключ surrogate key, то вы должны также имеют уникальные ограничения на natural key(s).

Важный бит, чтобы уйти с тем, что у вас должны быть уникальные ограничения на все кандидатов (независимо от того, являются ли они естественными или суррогатными). Затем вы должны выбрать тот, который проще всего ссылаться в Foreign Key, чтобы быть вашим Первичным ключом *.

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

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

  • Редактировать: Было указано, что термин Oracle «кластерная таблица» и «кластеризованный индекс» отличаются от Sql Server. Эквивалент того, о чем я говорю в Oracle-ese, - это Index Ordered Table, и он рекомендуется для таблиц OLTP, которые, я думаю, будут в центре внимания SO-вопросов. Я предполагаю, что если вы несете ответственность за большой хранилище данных OLAP, у вас уже должно быть собственное мнение о дизайне и оптимизации базы данных.

3

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

1 - уникальное ограничение может позволить nulls, но первичный ключ never разрешает ошибки. Если вы запускаете запрос с объединением в столбцах с нулевыми значениями, вы удаляете эти строки из результирующего набора данных, поскольку null не равен нулю. Таким образом, даже крупные компании могут делать ошибки учета и должны пересчитывать свою прибыль. Их запросы не отображали определенные строки, которые должны были быть включены в итоговое значение, потому что в некоторых столбцах их уникального индекса были нулевые значения. Shoulda использовал первичный ключ.

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

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

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

2

Нам нужно сделать различие между логическими конструкциями и физическими конструкциями и аналогично между теорией и практикой.

Для начала: с теоретической точки зрения, если у вас нет первичного ключа, у вас нет таблицы. Все просто. Итак, ваш вопрос заключается не в том, должен ли ваш стол иметь первичный ключ (конечно, это должно быть), а как вы его обозначаете в своей РСУБД.

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

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

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

1

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

я думаю, что единственная точка здесь та же старая дискуссия «естественная против ключей суррогатных» , потому что уникальные индексы и pk'ы - одно и то же.

перевод:

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

5

Вы должны всегда иметь первичный ключ.

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

Этот вопрос является вековой религиозной войной в поле БД.

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

0

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

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

1

Обычно я использую как PK, так и UNIQUE KEY. Потому что, даже если вы не укажете PK в своей схеме, вы всегда создаете для себя внутренне. Это верно как для SQL Server 2005, так и для MySQL 5.

Но я не использую столбец PK в своих SQL. Это для целей управления, таких как УДАЛЕНИЕ некоторых ошибочных строк, выяснение пробелов между значениями PK, если установлено значение AUTO INCREMENT. И имеет смысл иметь PK как числа, а не набор столбцов или массивы символов.

1

Я много писал на эту тему: если вы прочтете что-нибудь, то ясно, что я, вероятно, ссылался конкретно на Jet a.k.a. MS Access.

В Jet таблицы физически упорядочены в ПЕРВИЧНОМ КЛЮЧЕ с использованием неупорядоченного кластеризованного индекса (сгруппированы по компактности). Если таблица не имеет PK, но имеет ключи кандидата, определенные с помощью ограничений UNIQUE на столбцах NOT NULL, тогда движок будет выбирать один для кластерного индекса (если в вашей таблице нет кластерного индекса, то он называется кучей, возможно, не является таблицей вообще !) Как двигатель выбирает ключ кандидата? Может ли он выбрать тот, который включает в себя столбцы с нулевым значением? Я действительно не знаю. Дело в том, что в Jet единственный явный способ указать кластерный индекс для движка - использовать PRIMARY KEY. Разумеется, для ПК в Jet, например, есть другие способы использования, например. он будет использоваться в качестве ключа, если он исключен из объявления FOREIGN KEY в SQL DDL, но опять же, почему бы не быть явным.

Проблема с Jet заключается в том, что большинство людей, создающих таблицы, не знают или не заботятся о кластеризованных индексах. Фактически, большинство пользователей (я ставлю) помещают столбец Autonumber автоинкремента в каждую таблицу и определяют PRIMARY KEY исключительно в этом столбце, не создавая никаких уникальных ограничений для ключа естественного ключа и кандидата (можно ли фактически считать столбец автоинкремента ключ, не подвергая его конечным пользователям, - это еще одна дискуссия сама по себе). Я не буду вдаваться в подробности о кластеризованных индексах здесь, но достаточно сказать, что IMO - единственный столбец автоинкремента, редко подходит для идеального выбора.

Независимо от того, какой вы SQL-двигатель, выбор PRIMARY KEY является произвольным и зависит от двигателя. Обычно двигатель будет придать особое значение ПК, поэтому вы должны выяснить, что это такое, и использовать его в своих интересах.Я призываю людей использовать NOT NULL UNIQUE ограничения в надежде, что они будут уделять больше внимания всем ключам-кандидатам, особенно когда они решили использовать столбцы «autonumber», которые (должны) не имеют смысла в модели данных. Но я предпочел бы, чтобы народ выбрал один хорошо рассмотренный ключ и использовал PRIMARY KEY, вместо того, чтобы поместить его в колонку автоинкремента по привычке.

Должны ли все столы иметь ПК? Я говорю «да», потому что в противном случае, по крайней мере, вы упускаете из виду небольшое преимущество, которое дает ПК, и в худшем случае у вас нет целостности данных.

BTW Chris OC делает здесь хороший момент о временных таблицах, для которых требуются первичные ключи с первичными ключами (строчные буквы), которые не могут быть реализованы с помощью простых ограничений PRIMARY KEY (ключевые слова SQL в верхнем регистре).

0

Я думал об этой проблеме. Если вы используете уникальную, вы повредите 2. NF. В соответствии с этим каждый атрибут non-pk должен быть в зависимости от ПК. Пара атрибутов в этом уникальном ограничении должна рассматриваться как часть ПК.

извините за ответ на это 7 лет спустя, но не хотел начинать новое обсуждение.

1

PRIMARY KEY

1. Null Это не позволяет нулевые значения. Из-за этого мы обращаемся к PRIMARY KEY = УНИКАЛЬНЫЙ КЛЮЧ + НЕ НУЖНЫЙ КОНСТРАКЦИЯ. 2. INDEX По умолчанию он добавляет кластерный индекс. 3. LIMIT В таблице может быть только одна ПЕРВИЧНАЯ КЛАВИША Столбец [с].

уникальный ключ

1. Нуль Позволяет нулевое значение. Но только одно значение Null. 2. INDEX По умолчанию он добавляет UNIQUE некластеризованный индекс. 3. LIMIT В таблице может быть несколько UNIQUE ключевых столбцов [s].

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