Причины не использовать автоинкрементное число для первичного ключа - PullRequest
17 голосов
/ 04 ноября 2008

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

Каковы преимущества использования такого метода (или просто создания идентификатора GUID) вместо простого использования идентификатора / автоматического номера?

Я не говорю о первичных ключах, которые на самом деле «означают» что-то вроде ISBN или кодов продуктов, просто уникальные идентификаторы.

Спасибо.

Ответы [ 16 ]

27 голосов
/ 04 ноября 2008

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

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

17 голосов
/ 04 ноября 2008

Нет ничего плохого в использовании AutoNumber, но есть несколько причин не делать этого. Тем не менее, как говорил Дакракот, использование собственного решения - не лучшая идея. Позвольте мне объяснить.

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

Во-вторых, другие базы данных не используют эту парадигму, и другие парадигмы, такие как последовательности Oracle, намного лучше. К счастью, можно имитировать последовательности Oracle, используя SQL Server. Один из способов сделать это - создать единую таблицу AutoNumber для всей вашей базы данных с именем MainSequence или чем-то еще. Никакая другая таблица в базе данных не будет использовать autonumber, но любой, кому нужен первичный ключ, сгенерированный автоматически, будет использовать MainSequence для его получения. Таким образом, вы получаете все встроенную производительность, блокировку, потокобезопасность и т. Д., О которых говорил dacracot, без необходимости создавать его самостоятельно.

Другим вариантом является использование GUID для первичных ключей, но я не рекомендую этого, потому что даже если вы уверены, что человек (даже разработчик) никогда не будет читать их, кто-то, вероятно, сделает это, и это сложно. И что более важно, вещи неявно преобразуются в int в T-SQL, но могут возникнуть большие проблемы, неявно приводящие к GUID. В основном они неудобны.

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

10 голосов
/ 04 ноября 2008

из CodingHorror :

GUID Плюсы

  • Уникальный для каждой таблицы, каждой базы данных, каждого сервера
  • Позволяет легко объединять записи из разных баз данных
  • Позволяет легко распределять базы данных по нескольким серверам
  • Вы можете генерировать идентификаторы где угодно, вместо того, чтобы обращаться к базе данных туда и обратно
  • В большинстве сценариев репликации все равно требуются столбцы GUID

GUID Минусы

  • Это в 4 раза больше, чем у традиционного 4-байтового значения индекса; это может иметь серьезные последствия для производительности и хранения, если вы не будете осторожны
  • Громоздкий для отладки (где userid = '{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}')
  • Сгенерированные GUID должны быть частично последовательными для лучшей производительности (например, newsequentialid () в SQL 2005) и для возможности использования кластерных индексов

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

6 голосов
/ 04 ноября 2008

Клиентам полезно иметь возможность предварительно выделить целую группу идентификаторов для выполнения массовой вставки без необходимости затем обновлять свои локальные объекты вставленными идентификаторами. Тогда есть вся проблема репликации, как упомянуто Галвегианом.

6 голосов
/ 04 ноября 2008

Метод приращения должен быть многопоточным. Если нет, вы можете не получить уникальные номера. Кроме того, это должно быть быстро, иначе это будет узким местом приложения. Встроенные функции уже учли эти два фактора.

3 голосов
/ 30 января 2009

Вот что с автоматически увеличивающимися целыми числами в качестве ключей:

Вы ДОЛЖНЫ опубликовать запись до того, как получите к ней доступ. Это означает, что до тех пор, пока вы не разместите запись, вы не сможете, например, подготовить связанные записи, которые будут сохранены в другой таблице, или по одной из множества других возможных причин, по которым может быть полезно иметь доступ к уникальной новой записи. id, перед публикацией.

Вышесказанное - мой решающий фактор, выбрать один или другой метод.

3 голосов
/ 30 января 2009

Моя основная проблема с автоинкрементными клавишами заключается в том, что им не хватает никакого значения

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

3 голосов
/ 04 ноября 2008

Использование уникальных идентификаторов позволит вам объединять данные из двух разных баз данных.

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

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

2 голосов
/ 04 ноября 2008

Одним из преимуществ является то, что он может позволить базе данных / SQL быть более кроссплатформенным. SQL может быть точно таким же на SQL Server, Oracle и т. Д. *

1 голос
/ 04 ноября 2008

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

...