Строки как первичные ключи в базе данных SQL

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

14 ответов


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


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


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


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

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


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

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


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

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

кроме того, какова ваша мотивация для выбора строк? Числовые клавиши автоматического приращения часто так много легче как хорошо. Это семантика? Удобства? Репликация / отключенные проблемы? Ваш ответ здесь может ограничить ваши параметры. Это также напоминает третий "гибридный" вариант, который вы забываете: Guids.


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

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

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

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

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


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

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


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

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

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


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

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

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


какова причина наличия строки в качестве первичного ключа?

Я бы просто установил первичный ключ в поле Auto incrementing integer и поместил индекс в поле string.

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

вы также можете контролировать количество строкового поля, которое получает индекс. Иными словами, вы можете сказать "индексировать только первые 5 символов" если вы думаете, что будет достаточно. Или если ваши данные могут быть относительно похожи, вы можете индексировать все поле.


с точки зрения производительности-да строка (PK) замедлит производительность по сравнению с производительностью, достигнутой с помощью целого числа(PK), где PK ---> первичный ключ.

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

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


может быть очень большое недоразумение, связанное со строкой в базе данных. Почти все думали, что представление чисел в базе данных более компактно, чем для строк. Они думают, что в db-s числа представлены как в памяти. Но это неправда. В большинстве случаев числовое представление более близко к строковому представлению, чем к другому.

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


по ASPNetUserIds по умолчанию 128 строки char и производительность очень хорошо.

Если ключ и чтобы быть уникальным в таблице, он должен быть ключом. Вот почему;

первичный строковый ключ = правильные отношения БД, 1 строковый ключ(первичный) и 1 строковый индекс(первичный).

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

чтобы использовать int identity key = неправильные отношения БД, 1 int key(Primary), 1 int index(Primary), вероятно, уникальный строковый индекс, и вручную, чтобы проверить ту же строку, не существует (что-то вроде проверки sql, возможно).

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