Надежна ли функция автоматической генерации первичного ключа в базах данных? - PullRequest
7 голосов
/ 22 февраля 2010

Я разработал веб-приложение, и различные клиенты могут одновременно хранить записи в этой базе данных.

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

Итак, мой вопрос: могу ли я рассчитывать на эту функцию авто-генерации ключей?

Не будет ли проблем, если различные пользователи будут хранить записи одновременно?

Ответы [ 6 ]

14 голосов
/ 22 февраля 2010

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

  • Вы не должны предполагать, что оно всегда будет увеличиваться с шагом ровно 1 (или независимо от того, что вы установили).
  • Вы не должны вставлять запись, а затем без использования транзакций ожидайте, что сможете выбрать max (id), чтобы получить идентификатор последней вставленной записи.
5 голосов
/ 22 февраля 2010

Я хотел бы добавить еще одну вещь, которую следует иметь в виду при использовании функции auto_inc в MySQL:

Представьте, что у вас есть таблица employees, которая использует auto_inc и (по любой причине) вторую таблицу с именем former_employees. Давайте далее притворимся, что каждому сотруднику будет присвоен уникальный идентификатор (следовательно, auto_inc), и он даже не потеряет его из-за увольнения или увольнения.

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

Теперь вот снимок двух таблиц (не обращайте внимания на маленькие идентификаторы):

employees                       former_employees
------------------------        ------------------------
id   |  name  |  ...            id   |  name  |  ...
------------------------        ------------------------
27   | Peter  |  ...            29   | Andrew |  ...
28   | Jacko  |  ...            30   | Dennis |  ...
32   | Paula  |  ...            31   | Lenny  |  ...
                                33   | JoDon  |  ...

Обратите внимание, что former_employees последний идентификатор равен 33 и что employees счетчик auto_inc равен 34 прямо сейчас.

Если вы выключите сервер на этом этапе и перезапустите его, employees auto_inc вернется к 33 !!! Это потому, что MySQL не сохраняет счетчик auto_inc между перезапусками !

Имейте это в виду, хотя. С уважением.

PS: Чтобы обойти эту «особенность», вам придется запускать хранимые процедуры, которые смотрят на former_employees последний идентификатор и устанавливают его, если он больше.

Примечание (S.Leske): Это относится к таблицам InnoDB, но не к таблицам MyISAM. Не знаю насчет других настольных движков.

2 голосов
/ 22 февраля 2010

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

0 голосов
/ 23 февраля 2010

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

Существует одно предостережение: вы можете вставлять дублированные значения в столбец, если вы вставляете их явно (если СУБД позволяет явно установить значение столбца autoinc, что большинство и делают). Это может показаться тривиальным, но вы можете установить «бомбы замедленного действия», если вы (случайно) вставите явное значение в столбец автоинжина, который больше текущего идентификатора автоинжина.

Это будет работать нормально до тех пор, пока счетчик autoinc не достигнет введенного вами значения, а затем "boom" (то есть нарушение ограничения).

Это может произойти, например, если вы копируете записи из другой базы данных или восстанавливаете резервную копию. У нас возникла проблема в наших системах, и теперь мы регулярно «ресинхронизируем» счетчики автоинкенации: после «опасного» обновления, такого как копирование всей БД, мы извлекаем наибольшее используемое значение для каждого столбца автоинжина и устанавливаем значение счетчика автоинкена +1.

0 голосов
/ 23 февраля 2010

Вы спрашиваете, возможно ли когда-либо получить дубликат ключа для столбца IDENTITY, который не имеет уникального ограничения? Да, это возможно (таким образом, необходимость в СБЕКЕ CHECKIDENT RESEED), хотя вероятность низкая. За последние пару десятилетий со мной случалось несколько случаев с SQL Server. Единственный способ надежно гарантировать, что любое поле будет уникальным, - это использовать ограничение уникальности (или ограничение первичного ключа).

0 голосов
/ 22 февраля 2010

Что вы подразумеваете под «надежным»?

Базы данных используют блокировки.

В базе данных нет нигде "одновременно". Ресурсы заблокированы, и доступ для записи сериализован.

Что ты спрашиваешь? Уточните, пожалуйста, «надежный» в вашем вопросе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...