Я много писал на эту тему: если вы прочтете что-нибудь, то ясно, что я, вероятно, ссылался конкретно на 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 в верхнем регистре).
Вы говорите, если это ключ, сделайте его ключом, если он уникален, сделайте его уникальным. Но на самом деле, что делает ключ ключевым и не уникальным? Каково ваше определение ключа * *? – Pacerier 2013-11-22 21:38:04
@Pacerier Предположим, у нас есть база данных для студентов. В этой базе данных ученики идентифицируются с основным номером студента. В таблице для студентов мы храним такие вещи, как SSN/SIN или другой региональный эквивалент. В рамках проверки ошибок при наборе ключей мы хотим, чтобы это поле было уникальным. Но это не ключевое поле. (Хотя это может быть, предполагая соответствие 1: 1 между StuID и SSN) Назначение номеров также может быть уникальным, но не ключевым. (Хотя я был бы более склонным назначать ученика в комнату, чем комнату для ученика) – 2013-11-28 13:48:21
В вашем примере почему бы не сделать SSN/SIN ключом? – Pacerier 2013-11-30 03:52:44