Подтвердить что ты не робот

Причины не использовать автоинкрементный номер для первичного ключа

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

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

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

Спасибо.

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

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

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

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

Ответ 3

из CodingHorror:

GUID Pros

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

Недостатки GUID

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

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

Ответ 4

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

Ответ 5

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

Ответ 6

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

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

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

Ответ 7

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

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

Ответ 8

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

Ответ 9

Здесь вещь с автоматическим добавлением целых чисел в качестве ключей:

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

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

Ответ 10

Единственная причина, по которой я могу думать, это то, что код был написан до того, как sequences были изобретены, и код забыл догнать;)

Ответ 11

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

Ответ 12

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

Ответ 13

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

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

Ответ 14

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

Один из недостатков GUID PK заключается в том, что соединения в поле GUID медленнее (если только это не изменилось в последнее время). Еще одним преимуществом использования GUID является то, что интересно попробовать и объяснить нетехническому менеджеру, почему GUID-столкновение маловероятно.

Ответ 15

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

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

Ответ 16

Гальвеевский ответ не обязательно верен.

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

Допустим, у нас есть 2 базы данных, которые мы хотим реплицировать. Мы можем настроить его следующим образом.

increment = 2
db1 - offset = 1
db2 - offset = 2

Это означает, что

db1 будет иметь ключи 1, 3, 5, 7....

db2 будет иметь ключи 2, 4, 6, 8....

Поэтому мы не будем сталкиваться с ключами при вставках.