Строки как первичные ключи в базе данных SQL - PullRequest
151 голосов
/ 05 февраля 2009

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

Ответы [ 14 ]

163 голосов
/ 05 февраля 2009

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

64 голосов
/ 05 февраля 2009

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

18 голосов
/ 21 марта 2012

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

12 голосов
/ 05 февраля 2009

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

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

6 голосов
/ 05 февраля 2009

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

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

4 голосов
/ 06 февраля 2009

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

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

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

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

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

4 голосов
/ 05 февраля 2009

Слишком много переменных. Это зависит от размера таблицы, индексов, характера строкового ключа домена ...

Обычно , целые числа будут быстрее. Но будет ли разница достаточно большой, чтобы о ней заботиться? Трудно сказать.

Кроме того, какова ваша мотивация выбора струн? Цифровые клавиши автоинкремента также часто намного проще . Это семантика? Удобство? Репликация / отключенные проблемы? Ваш ответ может ограничить ваши возможности. Это также напоминает о третьем «гибридном» варианте, который вы забыли: направляющие.

2 голосов
/ 21 августа 2014

Две причины использовать целые числа для столбцов PK:

  1. Мы можем установить идентичность для целочисленного поля, которое увеличивается автоматически.

  2. Когда мы создаем PK, база данных создает индекс (Cluster или Non Cluster), который сортирует данные до их сохранения в таблице. Используя идентификатор на ПК, оптимизатору не нужно проверять порядок сортировки перед сохранением записи. Это улучшает производительность на больших столах.

2 голосов
/ 05 февраля 2009

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

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

2 голосов
/ 05 февраля 2009

Индексы подразумевают множество сравнений.

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

Иногда, однако, быстрее использовать строку в качестве первичного ключа, чем создавать дополнительное соединение с таблицей string to numerical id.

...