Использовать специальные префиксы и autonumber для первичных ключей?
Сегодня утром мы провели встречу о том, как сохранить наш идентификатор для некоторых активов, которые мы имеем в нашей базе данных, которые мы создаем, и в результате создалось небольшое количество тепла, поэтому я решил обратиться к экспертам SO.
Структура таблицы, которая, как я считаю, должна иметь (короткая версия), выглядит следующим образом:
Пример 1)
- AssetId - int (32) - Основной ключ
- Тип - строка
поэтому некоторые примеры данных выглядят следующим образом:
==AssetId======Type===
12345 "Manhole"
155415 "Pit"
и др.
Другой член команды предложил что-то вроде этого:
Пример 2)
- AssetId - строка - первичный ключ
- Тип - строка
поэтому некоторые примеры данных выглядят следующим образом:
==AssetId======Type===
"MH12345" "Manhole"
"P155415" "Pit"
где мы делаем короткую версию типа и добавляем ее к передней части идентификатора и сохраняем ее в базе данных. Я видел несколько баз данных активов, которые делают это и никогда не применяют этот подход.
Мне никогда не нравилась идея использования строк в качестве идентификатора для сортировки. Я также чувствую, что он хранит бесполезную информацию только ради этого, когда у вас уже есть тип хранилища активов.
Какой подход вы бы взяли? И почему? Существуют ли какие-либо преимущества для использования подхода 1 более чем на 2?
EDIT: Да, я буду использовать AUTO_INCREMENT для подхода 1.
Ответы
Ответ 1
Обычно эмпирическое правило заключается в том, что никогда не использовать значимую информацию в первичных ключах (например, номер социального страхования или штрих-код). Простое автоинкрементное целое.
Однако, по-видимому, данные кажутся постоянными - в какой-то момент это может измениться (придет новое законодательство, и все SSN пересчитаны).
Ответ 2
Это решение между суррогатными и естественными ключами, первое из которых является суррогатным (или "техническим" ), а второе - естественным.
Я пришел к выводу, что вы почти всегда должны использовать суррогатные ключи. Если вы используете естественные ключи, они могут меняться и обновлять первичные/внешние ключи, как правило, не являются хорошей идеей.
Ответ 3
Я бы пошел на первое. Создание уникальных идентификаторов должно быть оставлено на сервере SQL, и вы не можете создавать созданные автоматически с использованием потоков, если они являются строками. Насколько я понимаю, вам придется как-то справиться с этим?
Скорость - еще один фактор. Работа с значениями int всегда будет быстрее строк. Я бы сказал, что есть другие преимущества в плане индексации, которые гораздо более опытный специалист SQL, чем я, мог бы уточнить;)
По моему опыту, наличие идентификаторов строк было неудачным.
Ответ 4
Ну, я хочу сделать несколько замечаний и предложений,
-
Подумайте о наличии отдельной таблицы для типа, скажем, с идентификатором столбца и Desc, затем введите в эту таблицу внешний ключ TypeId. Еще один шаг для нормализации вещи. Но это может быть нежелательно. Сделайте это, если вы считаете, что оно служит какой-то цели
-
Создание этой строки имеет смысл, если позже вы подумаете о переходе на UUID. Вам не нужно изменять тип данных, затем
[Отредактировано]
Я согласен с Cletus здесь. Этот суррогатный ключ оказался полезным в некоторых реальных проектах. Они позволяют изменять, и вы хорошо знаете, что изменение является единственной константой.
Ответ 5
Я лично считаю, что первый подход намного, намного лучше. Он позволяет программному обеспечению базы данных выполнять простые целочисленные сравнения, чтобы найти и отсортировать по ключу, что улучшит производительность работы таблицы (SELECT, сложные JOIN, по ключевым словам INDEX-запросы и т.д.).
Конечно, я предполагаю, что в любом случае вы используете какой-то метод автоинкремента для создания идентификаторов - либо последовательность, либо AUTO_INCREMENT, либо что-то подобное. Сделайте мне одолжение и не создавайте их в своем программном коде, ОК?
Ответ 6
Я бы выбрал числовой первичный ключ для повышения производительности. Целочисленные сравнения намного дешевле, чем сравнение строк, и он будет занимать меньше места в БД.
Ответ 7
Я предпочитаю пример 1 по причинам, о которых вы упомянули, и единственным аргументом, который я могу придумать для использования примера 2, является то, что вы пытаетесь разместить идентификаторы строк из существующей базы данных (довольно часто), однако даже в этом сценарии я предпочитаю для использования следующего подхода.
==AssetId(PK)==Type========DeprecatedId====
12345 "Manhole" "MH64247"
155415 "Pit" "P6487246"
Ответ 8
Если у ваших активов уже есть уникальные идентификаторы (например, сотрудники с идентификаторами сотрудников), используйте их. Нет смысла создавать другой уникальный идентификатор.
С другой стороны, если нет естественного уникального идентификатора, используйте самый короткий из них, который может обеспечить достаточное количество уникальных ключей для ожидаемого размера таблицы (например, целого). Это потребует меньше места на диске и, вероятно, будет быстрее. И, кроме того, если вам понадобится использовать строковый ключ позже, это простое задание замещения:
- добавить первичный ключ sting в таблицу активов.
- добавить строковый внешний ключ для отправки таблиц.
- обновлять строковые отношения с помощью простой команды UPDATE с использованием целых отношений.
- добавить ограничения внешнего ключа для столбцов столбцов.
- удалить ограничения внешнего ключа для целых столбцов.
- удалить целые столбцы вообще.
Некоторые из этих шагов могут быть проблематичными для конкретной СУБД, возможно, требуют, чтобы таблица выгружала/перезагружалась для удаления целых столбцов первичного ключа, но эта стратегия в основном требуется.
Ответ 9
Единственное преимущество примера 2 состоит в том, что вы легко можете просто указать только из первичного ключа, в какой строке этой таблицы применяется этот ключ. Идея хорошая, но полезна ли она, зависит от ваших стратегий ведения журнала и ошибок. Вероятно, он имеет недостаток производительности, поэтому я бы не использовал его, если вы не можете назвать некоторые конкретные причины его использования.
(Вы можете получить это преимущество, используя глобальную последовательность для создания числовых клавиш или используя разные числовые диапазоны, последние цифры или что-то еще. Тогда у вас нет недостатков производительности, но, возможно, вы не найдете таблицу так легко.)