Первичный ключ базы данных -> Поле идентификатора И поле имени? - PullRequest
1 голос
/ 14 апреля 2009

все мои таблицы имеют поле Id определенного типа (UserId, PostId, FooId и т. Д.). Я обычно делаю это Первичный ключ .

Таблица, которую я имею, называется Countries. Имеет

CountryId SMALLINT
Name VARCHAR(100)  -- Yes, english country names only, in this column.
AndSomeOtherFields.

Теперь я знаю, что Name должен быть уникальным. Все названия стран являются уникальными. Это хорошо / плохо / ру-ро, если я сделаю PrimaryKey == CountryId ASC и Name ASC?

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

спасибо, любезно.

Ответы [ 6 ]

6 голосов
/ 14 апреля 2009

Создание первичного ключа CountryId и Name не гарантирует уникальность имен. Это просто гарантирует, что каждая CountryId - Name пара уникальна, и, очевидно, CountryId уже уникальна, будучи «идентификатором». Таким образом, вы можете иметь, например, 1-US и 19-US, так как пары уникальны.

Единственная причина сделать их первичным ключом - это если вы будете часто выполнять запросы, в которых в выражении Where используются и CountryId, и Name. Первичный ключ по умолчанию создает кластеризованный индекс, который физически сортирует таблицу, поэтому очень быстро выполняет поиск строк по этим предикатам.

Еще один важный момент, который необходимо поднять, заключается в том, что в вашем конкретном примере вы храните список стран, который а) очень короткий и б) мало что меняет. Поиски по этой таблице будут чрезвычайно быстрыми, независимо от того, что вы делаете. Даже если SQL Server каждый раз выполняет полное сканирование таблицы, вы, вероятно, даже не заметите. Вам не нужно беспокоиться о фрагментации страницы. Вы можете просто пропустить столбец ID и использовать Name в качестве первичного ключа.

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

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

1 голос
/ 14 апреля 2009

Создать уникальный индекс для столбца Name.

1 голос
/ 14 апреля 2009

Если имя становится PK, это не всегда лучшее решение, я считаю, что CountryId достаточно в качестве PK для вашей таблицы, однако, если Name - это поле, которое вы будете использовать для запроса, то есть: выбирает, присоединяет вас следует индексировать это поле таким образом, фильтрация запросов по этому полю улучшит его скорость

удачи :) 1003 *

0 голосов
/ 14 апреля 2009

Если вам нужно обеспечить уникальность, используйте ограничение.

0 голосов
/ 14 апреля 2009

Названия стран, как известно, меняются, не меняя идентичность страны. Это говорит о том, что имя не должно быть частью PK.

0 голосов
/ 14 апреля 2009

Единственное, о чем я могу думать, довольно очевидно: ваш индекс будет немного больше. Сказав это, это не такое уж большое дело, потому что на вашем столе будут храниться только страны. Но зачем вам такой индекс? Если вы сортируете по CountryId , то сортировка по Name в качестве второго поля не имеет смысла. Вы всегда получите один и тот же заказ.

Одна из действительно плохих идей - иметь внешние ключи, указывающие на большой первичный ключ, поэтому убедитесь, что если вы используете этот первичный ключ, ваши внешние ключи, указывающие на Страны , по-прежнему используют только CountryId столбец.

...