VARCHAR как внешний ключ / первичный ключ в базе данных хорошо или плохо? - PullRequest
32 голосов
/ 20 января 2010

Лучше ли использовать в качестве внешних ключей идентификатор nr: s вместо VARCHARS? И лучше ли использовать идентификатор nr: s вместо VARCHARS в качестве первичных ключей? Под идентификатором nr я подразумеваю INT!

Вот что у меня сейчас:

category table:
cat_id ( INT ) (PK)
cat_name (VARCHAR)

category options table:
option_id ( INT ) (PK)
car_id ( INT ) (FK)
option_name ( VARCHAR ) 

Я мог бы подумать:

category table:
cat_name (VARCHAR) (PK)

category options table:
cat_name ( VARCHAR ) (FK)
option_name ( VARCHAR ) ( PK )

Или я тут совершенно не так думаю?

Ответы [ 7 ]

30 голосов
/ 20 января 2010

Проблема использования VARCHAR для любого КЛЮЧА заключается в том, что они могут содержать БЕЛЫЙ ПРОБЕЛ. Пробел состоит из ЛЮБОГО не читаемого на экране символа, такого как табуляция пробелов, возврат каретки и т. Д. Использование VARCHAR в качестве ключа может усложнить вам жизнь, когда вы начнете искать, почему таблицы не возвращают записи с дополнительными пробелами в конце их ключей.

Конечно, вы МОЖЕТЕ использовать VARCHAR, но вы должны быть очень осторожны с входом и выходом. Они также занимают больше места и, вероятно, работают медленнее при выполнении запросов.

Целочисленные типы имеют небольшой список из 10 допустимых символов, 0,1,2,3,4,5,6,7,8,9 . Это гораздо лучшее решение для использования в качестве ключей.

Вы всегда можете использовать целочисленный ключ и использовать VARCHAR в качестве УНИКАЛЬНОГО значения, если хотите использовать преимущества более быстрого поиска.

11 голосов
/ 20 января 2010

Когда я занимаюсь проектированием, я спрашиваю себя: есть ли у меня что-либо в этих данных, которое, я могу гарантировать, будет ненулевым, уникальным и неизменным ? Если так, то это кандидат на первичный ключ. Если нет, я знаю, что должен генерировать значение ключа для использования. Предполагая, что ключ-кандидат оказался VARCHAR, я смотрю на данные. Она достаточно короткая (например, 20 символов или меньше)? Или поле VARCHAR довольно длинное? Если он короткий, его можно использовать в качестве ключа - если он длинный, возможно, лучше не использовать его в качестве ключа (хотя, если он рассматривается как первичный ключ, мне, вероятно, все равно придется индексировать его). По крайней мере, часть моей озабоченности заключается в том, что первичный ключ нужно будет проиндексировать и, возможно, он будет использоваться как внешний ключ из какой-то другой таблицы. Сравнение полей VARCHAR, как правило, медленнее, чем сравнение числовых полей (особенно двоичных числовых полей, таких как целые числа), поэтому использование длинного поля VARCHAR в качестве ключа может привести к снижению производительности. YMMV.

10 голосов
/ 21 октября 2012

Мои 2 цента:

С точки зрения производительности использование CHAR или VARCHAR в качестве первичного ключа или индекса является кошмаром.

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

4 голосов
/ 20 января 2010

Если вы внесете название категории в идентификатор, у вас возникнут проблемы, если вы когда-нибудь решите переименовать категорию.

3 голосов
/ 20 января 2010

с помощью int вы можете хранить до 2 миллиардов в 4 байтах с varchars, для которых вам не нужно иметь около 10 байтов или около того, чтобы хранить это, если вы используете varchars, то есть также 2-байтовые издержкитеперь вы добавляете 6 дополнительных байтов в каждом PK и FK + 2-байтовые накладные расходы varchar

3 голосов
/ 20 января 2010

Я бы сказал, что можно использовать VARCHAR в качестве ПЕРВИЧНЫХ и ИНОСТРАННЫХ КЛЮЧЕЙ .

Единственная проблема, на которую я мог обратить внимание, это если у вас есть таблица, скажем, Инструменты (обмен инструментами), и вы создаете ПЕРВИЧНЫЙ / ИНОСТРАННЫЙ КЛЮЧ как VARCHAR и случается, что CODE меняется.

Это происходит на фондовых биржах и требует от вас переименования всех ссылок на этот КОД , где в качестве идентификатора nr вам этого не потребуется.

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

EDIT

Когда я говорю «КОД», я имею в виду «Код тикера», скажем, «ХОРОШО», или любую другую акцию. Эти коды могут изменяться со временем, скажем, вы смотрите на инструменты Dirivative / Future.

1 голос
/ 20 января 2010

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

Если вы используете CHAR или VARCHAR в качестве первичного ключа, в какой-то момент вы в конечном итоге будете использовать его в качестве внешнего ключа. Когда дело доходит до этого, как говорит @astander, это зависит от ваших данных и того, как вы собираетесь их использовать.

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