Я разрабатываю небольшую базу данных SQL для использования в веб-приложении.
Скажем, в определенной таблице есть поле «Имя», для которого никакие две строки не могут иметь одинаковое значение. Однако пользователи смогут изменить поле «Имя» в любое время.
Первичный ключ из этой таблицы будет использоваться как внешний ключ в других таблицах. Поэтому, если поле Name использовалось в качестве первичного ключа, любые изменения необходимо было бы распространить на эти другие таблицы. С другой стороны, требование уникальности будет выполняться автоматически.
Моим инстинктом было бы добавить целочисленное поле в качестве первичного ключа, которое могло бы автоматически заполняться базой данных. Есть ли смысл в этом поле или это будет пустой тратой времени?





Я бы сам использовал сгенерированный ПК по указанным вами причинам. Кроме того, индексирование и сравнение по целым числам выполняется быстрее, чем по строкам. Вы также можете поместить уникальный индекс в поле имени, не делая его первичным ключом.
Это общепринятый способ обработки первичных ключей. Вы никогда не должны выбирать столбец для своего первичного ключа, где его значение может быть изменено - так как затем вы попадаете в каскадное обновление для всех таблиц с этим ключом в качестве основного ключа.
Первичный ключ должен быть уникальный для каждой строки. Целочисленное значение auto_increment - очень хорошая идея, и если у вас нет других идей о заполнении первичного ключа, то это лучший способ.
Да - и, как правило, всегда для каждого стола.
Вам определенно не следует использовать изменяемое поле в качестве первичного ключа, и в подавляющем большинстве случаев вы не хотите использовать поле, которое имеет какое-либо другое назначение, в качестве первичного ключа.
Это основная передовая практика для схем БД.
Целочисленный первичный ключ - это всегда хорошо с точки зрения производительности. Все ваши отношения будут намного эффективнее с целочисленным первичным ключом. Например, JOIN будет намного быстрее (SQL Server).
Это также позволит вам в будущем вносить изменения в базу данных. Довольно часто у вас есть столбец уникального имени только для того, чтобы позже узнать, что имя у него вовсе не уникальное.
Прямо сейчас вы можете усилить уникальность столбца Имя, добавив к нему индекс.
Я бы использовал автоматически сгенерированное поле идентификатора для первичного ключа. С таблицами, основанными на целочисленных идентификаторах, легче соединяться, чем с текстом. Кроме того, если поле Имя обновляется часто, если бы оно было первичным ключом, база данных подверглась бы нагрузке из-за более частого обновления индекса в этом поле.
Если поле Имя всегда уникально, вы все равно должны пометить его как уникальное в базе данных. Однако часто будет возможность (возможно, не сейчас, но, возможно, в будущем в вашем случае) двух одинаковых имен, поэтому я не рекомендую это.
Еще одно преимущество использования идентификаторов - в том случае, если вам требуется отчетность по вашей базе данных. Если у вас есть отчет, который вам нужен для данного набора имен, фильтр идентификаторов в отчете останется неизменным, даже если имена могут измениться.
То, что вы описываете, называется суррогатный ключ. Подробный ответ см. В Статья в Википедии.
Если вы живете в разреженных кругах математиков-теоретиков (например, С. Дэйт в стране, где-нет-нулей, потому что все значения данных известны и верны), то первичные ключи могут быть построены из компоненты данных, которые идентифицируют идеализированную платоническую сущность, на которую вы ссылаетесь (например, имя + день рождения + место рождения + имена родителей), но в беспорядочных «синтетических ключах» реального мира, которые могут идентифицировать ваши реальные сущности в пределах контекст вашей базы данных - гораздо более практичный способ сделать что-то. (И поля, допускающие значение NULL, могут быть очень полезны. Возьмите это, люди из теории реляционного дизайна!)
Будем надеяться, что Celko никогда не станет укладчиком, или нас всех ждут серьезные разборки.
О, когда это случится, нам всем станет плохо!
Первичный ключ для записи должен быть уникальным и постоянный. Если запись, естественно, имеет простой ключ, который удовлетворяет обоим из них, используйте его. Однако они появляются нечасто. Для записи о человеке имя человека не является ни уникальным, ни постоянным, поэтому вам в значительной степени придется использовать автоинкремент.
Единственное место, где работают естественные ключи, - это кодовая таблица, например таблица, отображающая значение статуса в его описание. Нет смысла давать «Активному» первичный ключ 1, «Задержке» - первичному ключу 2 и т. д. Когда так же легко дать «Активному» первичный ключ «ACT»; «С задержкой», «DLY»; «В ожидании», «ДВУ» и так далее.
Также обратите внимание: некоторые говорят, что вам следует использовать целые числа вместо строк, потому что они быстрее сравниваются. Не совсем так. Сравнение двух 4-байтовых символьных полей займет ровно столько же времени, сколько и сравнение двух 4-байтовых целочисленных полей. Более длинная строка, конечно, займет больше времени, но если вы будете использовать короткие коды, разницы нет.
Другой пример: country_code (US, UK и т. д.). Люди склонны использовать 4-байтовый INT, тогда как CHAR(2) CHARACTER SET ascii занимает всего 2 байта и работает лучше по другим причинам. Когда Чехословакия разделится на Чехию и Словакию, вам придется писать код для любого дизайна первичного ключа.
Хотя быстрее искать и присоединяться к целочисленному столбцу (как отмечали многие), еще быстрее вообще никогда не присоединяться. Сохраняя естественный ключ, вы часто можете избавиться от необходимости в объединении.
Для небольшой базы данных обновления CASCADE для ссылок внешнего ключа не окажут большого влияния на производительность, если только они не будут меняться очень часто.
При этом вам, вероятно, следует использовать целое число или GUID в качестве суррогатный ключ в этом случае. Первичный ключ с возможностью обновления по умолчанию - не лучшая идея, и если у вашего приложения нет веских причин для бизнеса, чтобы быть уникальным по имени, вы неизбежно столкнетесь с конфликтами.
Если столбец вашего имени будет изменяться, это не лучший кандидат на роль первичного ключа. Первичный ключ должен определять уникальную строку таблицы. Если это можно изменить, на самом деле это не так. Не зная подробностей о вашей системе, я не могу сказать, но сейчас хорошее время для суррогатного ключа.
Я также добавлю это в надежде развеять мифы об использовании автоматически увеличивающихся целых чисел для всех ваших первичных ключей. Их использование НЕ всегда улучшает производительность. На самом деле, довольно часто бывает с точностью до наоборот. Если у вас есть автоматически увеличивающийся столбец, это означает, что каждый INSERT в системе теперь имеет дополнительные накладные расходы на создание нового значения.
Кроме того, как указывает Марк, с суррогатными идентификаторами во всех ваших таблицах, если у вас есть цепочка связанных таблиц, чтобы перейти от одной таблицы к другой, вам, возможно, придется объединить все эти таблицы вместе, чтобы пройти по ним. С естественными первичными ключами это обычно не так. Объединение 6 таблиц с целыми числами обычно будет медленнее, чем соединение двух таблиц с помощью строки.
Вы также часто теряете возможность выполнять операции на основе наборов, когда у вас есть автоматически увеличивающиеся идентификаторы для всех ваших таблиц. Вместо того, чтобы вставлять 1000 строк в родительскую таблицу, а затем вставлять 5000 строк в дочернюю таблицу, теперь вам нужно вставлять родительские строки по одной в курсор или какой-либо другой цикл, чтобы получить сгенерированные идентификаторы, чтобы вы могли их назначить родственным детям. Я видел, как 30-секундный процесс превратился в 20-минутный процесс, потому что кто-то настоял на использовании автоматически увеличивающихся идентификаторов для всех таблиц в базе данных.
Наконец (по крайней мере, по причинам, которые я перечисляю здесь - конечно, есть и другие), использование автоматически увеличивающихся идентификаторов во всех ваших таблицах способствует плохому дизайну. Когда дизайнеру больше не нужно думать о том, каким может быть естественный ключ для таблицы, это обычно приводит к ошибочным дубликатам, попадающим в данные. Вы можете попытаться избежать проблемы с уникальными индексами, но, по моему опыту, разработчики и дизайнеры не прилагают дополнительных усилий, и через год использования их новой системы они обнаруживают, что данные беспорядочные, потому что в базе данных не было правильные ограничения данных с помощью естественных ключей.
Конечно, есть время для использования суррогатных ключей, но использование их вслепую во всех таблицах почти всегда является ошибкой.
Обратите внимание, что снижение производительности за вставку в родительскую и дочернюю таблицы необходимо только в том случае, если вы настаиваете на создании родительского, затем дочернего, затем родительского, затем дочернего. Просто сначала создайте 1K родителей, а затем 5K детей.
В дополнение ко всему сказанному, рассматривать использует UUID в качестве PK. Это позволит вам создавать уникальные ключи для нескольких баз данных.
Если вам когда-нибудь понадобится экспортировать / объединить данные с другой базой данных, то данные всегда останутся уникальными, а отношения можно будет легко поддерживать.
одно обычно встречается исключение для «системных» данных. т.е. вещи, которые вы определяете сами, поля статуса и т.д.