Будет ли SQL Server 2005 наказывать меня за использование nvarchar (50) в качестве первичного ключа вместо целого числа? - PullRequest
12 голосов
/ 22 октября 2008

Я рассматриваю изменение некоторых таблиц для использования nvarchar (50) в качестве первичного ключа вместо первичного ключа int. Использование int ID для ключа на самом деле не имеет значения, это интересующая меня строка. Какой тип снижения производительности произойдет, или где вы исследуете это? Кроме резки и попробуйте это.

Ответы [ 5 ]

26 голосов
/ 22 октября 2008

Вы столкнулись с одной из главных "священных войн" в разработке баз данных. Дебаты, о которых вы говорите, - это аргумент «суррогат против естественного ключа», который бушует до тех пор, пока существуют СУРБД (насколько я могу судить).

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

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

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

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

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

Системное проектирование и СУБД

TechRepublic

Блог Тони Роджерсона

Надеюсь, это поможет.

5 голосов
/ 22 октября 2008

Рассмотрите возможность использования суррогатного ключа (первичного ключа int) в качестве первичного ключа / ключа кластерного индекса. Проблема с использованием nvarchar (50) в качестве первичного ключа / ключа кластерного индекса заключается в том, что ваша таблица будет упорядочена по этому ключу, что означает, что она может сильно фрагментироваться, и что любые другие индексы будут нести бремя ссылки на этот тяжелый первичный ключ.

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

Я думаю, что очень мало ситуаций, в которых первичный ключ nvarchar (50) имел бы смысл.

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

1 голос
/ 22 октября 2008

Для производительности я обычно спрашиваю следующее:

  • сколько строк? 1 000 или 1 000 000 или 10 000 000 ??

  • на каком сервере он сидит? (память, дисковое пространство)

Я бы профилировал это, а затем увидел. Обычно для меня узким местом является не база данных, это плохо написанный код, плохо развернутый и т. Д. И т. Д. ...

0 голосов
/ 22 октября 2008

Чтобы окончательно сжечь все аргументы, выдвинутые лидерами решения о естественном ключе ( ср. Суррогат против войны с естественным ключом ), и чтобы сделать его коротким, я должен сказать, что суррогатные ключи ВСЕГДА работают, в то время как естественные ключи имеют слабую склонность приводить к проблемам и разочарованию, обычно в неожиданные времена.

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

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

Tbl_whatever
     id_whatever, unique identifier, primary key
     code_whatever, nvarchar(your favorite length), indexed
     .....

Где id_ - префикс первичного ключа, а code_ используется для «естественного» индексированного поля

0 голосов
/ 22 октября 2008

Почему ЮНИКОД? например если я переведу английское слово на китайские иероглифы хань, будут ли они считаться дубликатами?

Почему переменная? Фиксированная ширина - хорошая физическая характеристика ключа.

Почему 50 символов? Это большое количество ключей для пользователей (я согласен, что «int ID для ключа действительно не имеет значения» и думаю, что так называемые «суррогатные ключи» никогда не должны передаваться конечным пользователям, кстати).

Кроме того, для меня NVARCHAR(50) немного "пахнет": возможно, по умолчанию Microsoft, прямой порт из MS Access? Это не означает, что вы не уделили должного внимания и внимания своему ключу, конечно, только одну из тех вещей, которые, возможно, стоит рассмотреть.

Ох, подожди: ты имел в виду именно ПЕРВИЧНЫЙ КЛЮЧ, верно? Предполагая, что вы явно используете один (на таблицу) кластеризованный индекс, обозначение AFAIK PRIMARY KEY не имеет физических последствий для среды SQL Server. Конечно, все ваши ключи-кандидаты должны быть охвачены ограничениями NOT NULL UNIQUE; тот, который вы выбираете для продвижения на ПЕРВИЧНЫЙ ключ, является произвольным.

...