Зачем использовать int в качестве первичного ключа таблицы поиска?

30

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

Я понимаю, что использование nvarchar (50) вместо int заняло бы намного больше места, если оно связано с таблицей со многими записями.

С другой стороны, непосредственное использование значения подстановки в принципе избавило бы нас от объединения. Я могу себе представить, что это будет большая экономия, если объединение всегда требуется (мы работаем над веб-приложением, так что это немало).

Каковы преимущества использования первичного ключа int (особенно для таблицы поиска), кроме того, что он является «стандартным делом»?

Жако Брирс
источник
4
Вы можете найти хорошую информацию и, возможно, даже нужный ответ в этих 2 предыдущих вопросах: есть ли преимущество первичного ключа, который включает в себя все столбцы таблицы? и символ против целочисленных первичных ключей .
Marian

Ответы:

23

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

Просто прочитайте ваш комментарий к Сэнди - возможно, в этом случае вам действительно нужна проверка ограничений , а не таблица внешнего ключа / поиска, например:

create table icecream (flavour varchar(10))
go
alter table icecream add constraint ck_flavour check (flavour in ('Orange', 'Pista', 'Mango'))
go
insert into icecream (flavour) values ('Orange')
go
insert into icecream (flavour) values ('Vanilla')
go

Запустите это, и вы получите:

(1 row(s) affected)
Msg 547, Level 16, State 0, Line 1
The INSERT statement conflicted with the CHECK constraint "ck_flavour". The conflict occurred in database "GAIUSDB", table "dbo.icecream", column 'flavour'.
The statement has been terminated.

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

Gaius
источник
@ Gaius- Хороший пример ... Я предпочитаю не использовать проверку ограничений для этого типа сценария; основная причина, по которой он не будет обслуживаться (вы указали это как недостаток).
CoderHawk
1
@ Sandy Это действительно зависит от данных, как часто они будут меняться, и где еще они будут использоваться. Например, если ограничение должно выполняться БД, но значения могут также использоваться для заполнения раскрывающегося меню или в отчете, тогда более подходящим будет внешний ключ. В любом случае, я бы посоветовал не делать это в приложении.
Гай
7

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

Таблица поиска используется для отображения информации из одной таблицы на основе значения поля внешнего ключа в другой таблице. Например, рассмотрим таблицу заказов в базе данных продаж. Каждая запись в таблице «Заказы» содержит идентификатор клиента, указывающий, какой клиент разместил заказ. CustomerID - это внешний ключ, указывающий на запись клиента в таблице Customers. При представлении списка заказов (из таблицы «Заказы») может потребоваться отобразить фактическое имя клиента, а не идентификатор клиента. Поскольку имя клиента находится в таблице клиентов, а вы представляете данные из таблицы «Заказы», ​​необходимо создать таблицу поиска, которая принимает значение CustomerID в записи «Заказы» и использует это значение для навигации по отношениям и возврата более читаемый, имя клиента.

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

Ароматизатор стол

Orange  
Pista  
Mango

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

CoderHawk
источник
1
Хороший момент, цель моей таблицы поиска в основном состоит в том, чтобы обеспечить применение различных значений, которые столбец может иметь через ограничение внешнего ключа. Я согласен, что жесткое кодирование в приложение может быть другим способом решения этой проблемы.
Жако Брирс
@Jaco Briers - см. Ответ Гая ... используйте проверку ограничений ...
CoderHawk,
7

Поскольку вы уточнили свой вопрос как «специально для справочной таблицы», ответ, вероятно, упрощен до «экономит место».

Я думаю, что если вы удалите этот классификатор, ваш вопрос станет таким: «Зачем использовать суррогатные ключи над натуральными?». Я написал следующее в поддержку суррогатных ключей:

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

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

dba4life
источник
3

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

Таблица поиска с числовым первичным ключом требует только изменения значения в таблице поиска.

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

Сьюзен Кеннеди
источник
2

Когда вы определяете ID, вы также можете гарантировать уникальность. Но когда вы принимаете, например, электронную почту, за уникальный идентификатор, вы переносите ответственность за уникальность на ненадежную 3-ю сторону.

Войта Рылько
источник