Должен ли я использовать целочисленные первичные идентификаторы? - PullRequest
2 голосов
/ 18 апреля 2010

Например, я всегда генерирую поле автоинкремента для таблицы пользователей, но я также указываю уникальный индекс для их имен пользователей. Существуют ситуации, когда мне сначала нужно получить userId для данного имени пользователя, а затем выполнить требуемый запрос или использовать JOIN в желаемом запросе. Это 2 поездки в базу данных или соединение с индексом varchar.

Должен ли я использовать целочисленные первичные идентификаторы?

Есть ли реальный выигрыш в производительности для INT по сравнению с small VARCHAR?

Ответы [ 4 ]

6 голосов
/ 18 апреля 2010

Имеется несколько преимуществ наличия суррогатного первичного ключа, в том числе:

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

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

3 голосов
/ 18 апреля 2010

Это не только производительность. Никогда не следует указывать значимое значение по причинам, которые хорошо документированы в других местах.

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

2 голосов
/ 18 апреля 2010

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

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

Сравните это с первичным ключом guid - новые строки должны быть вставлены в середину таблицы, потому что направляющие непоследовательны, что делает вставки очень неэффективными.

0 голосов
/ 18 апреля 2010

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

  1. Использование 32-битной системы займет всего 4 байта. Предположительно, ваши имена пользователей будут длиннее четырех символов, отличных от Unicode, и, следовательно, будут занимать более 4 байтов пространства. Чем больше используется места, тем меньше данных помещается на странице, тем толще индекс и тем больше операций ввода-вывода.

  2. Ваши столбцы персонажей будут требовать использования varchar вместо char, если вы не заставите всех иметь имена пользователей одинакового размера. Это также окажет незначительное влияние на производительность и хранение.

  3. Если вы не используете двоичную сортировку, система должна выполнять сравнительно сложное сопоставление при сравнении двух строк. Используются ли в двух столбцах одинаковые сопоставления? Для каждого персонажа они одинаковы? Каковы правила расположения и акцента с точки зрения соответствия? и так далее. Хотя это можно сделать быстро, это большая работа, которая в очень больших таблицах может иметь значение по сравнению с сопоставлением по целому числу.

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

...