Когда использовать первичный ключ с автоматическим увеличением и когда это не так?

Я пытаюсь выяснить "лучшие практики" для принятия решения о том, следует ли добавлять автоматически увеличивающееся целое число в качестве первичного ключа в таблицу.

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

Было бы так же верно, если бы у меня была таблица книг? Должен ли я использовать ISBN или автоматически увеличивающееся целое для первичного ключа? Или таблица сотрудников, содержащих каждого человека SSN?

Ответ 1

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

Термин, который вы должны искать: суррогатные ключи.

Надеюсь, что это поможет.

Ответ 2

Это очень спорный вопрос, с большим количеством эмоций с обеих сторон.

По моему скромному мнению, если есть хороший, доступный натуральный ключ - как ISBN - я его использую. В любом случае я собираюсь хранить его в базе данных. Да, естественный ключ обычно больше, чем целочисленный ключ автоинкремента, но я думаю, что эта проблема раздута. Сегодня дисковое пространство дешево. Я бы больше волновался об этом, и это заняло больше времени. Если вы говорили о 80-байтовом текстовом поле в качестве первичного ключа, я бы сказал нет. Но если вы думаете об использовании 10-байтового ISBN вместо 8-байтового большого целого, я не могу себе представить, что это приносит большую часть производительности.

Иногда есть преимущество в производительности для естественных ключей. Предположим, например, что я хочу найти, сколько копий данной книги было продано. Меня не волнует какая-либо информация из основной записи книги. Если первичный ключ ISBN, я могу просто написать "select count (*) из продажи, где isbn = '143573338X'". Если бы я использовал ключ автоинкремента, мне нужно было бы создать соединение для поиска isbn, и запрос будет более сложным и медленным, например "select count (*) из book join sale using (bookid), где isbn = '143573338X'". (И я могу заверить вас, что, поскольку этот конкретный ISBN для моей книги, количество записей о продаже очень невелико, так что объединение и чтение одной дополнительной записи - большая процентная разница!)

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

С другой стороны, если нет хорошего, очевидного естественного ключа, не пытайтесь суетиться вместе с сумасшедшим. Я видел, как люди пытаются сделать естественный ключ, объединив первые 6 букв имени клиента, его год рождения и его почтовый индекс, а затем молись, чтобы это было уникально. Такая глупость просто создает проблемы для вас самих. Часто люди в конечном итоге берут порядковый номер, чтобы обеспечить его уникальность в любом случае, и в этот момент, зачем беспокоиться? Почему бы просто не использовать номер последовательности сам по себе в качестве ключа?

Ответ 3

У вас есть идея прямо здесь.

Автоинкремент должен использоваться как уникальный ключ, если уже не существует уникального ключа о моделях, которые вы моделируете. Итак, для Elements вы можете использовать Atomic Number или Books номер ISBN.

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

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

Ответ 4

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

Ответ 5

Я пытаюсь выяснить "лучшие практики" для принятия решения о том, следует ли добавлять автоматически увеличивающееся целое число в качестве первичного ключа в таблицу.

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

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

Да.

Было бы так же верно, если бы у меня была таблица книг? Должен ли я использовать ISBN или автоматически увеличивающееся целое для первичного ключа? Или таблица сотрудников, содержащих каждого человека SSN?

ISBNs/SS # s назначаются третьими лицами, и из-за их большого размера хранилища будет очень неэффективным способом однозначной идентификации строки. Помните, что PKeys полезны, когда вы присоединяетесь к таблицам. Зачем использовать большой формат данных, например ISBN, который будет представлять собой множество текстовых символов в качестве уникального идентификатора, когда доступен небольшой и компактный формат, например Integer?

Ответ 6

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

Ответ 7

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

Если вы должны использовать идентификатор с автоматическим увеличением, возможно, подумайте об использовании его как части ПК. Наденьте его на конец, чтобы сохранить уникальность.....

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