MySQL AUTO_INCREMENT не ОТКАТЫВАЕТ

64
задан revo 14 May 2019 в 11:36
поделиться

5 ответов

Позвольте мне указать на что-то очень важное:

Вы никогда не должны зависеть от числовых функций автоматически сгенерированных ключей.

таким образом, кроме сравнения их для равенства (=) или неравенства (< >), Вы не должны делать ничего больше. Никакие операторы отношения (< >), никакая сортировка по индексам, и т.д. Если необходимо отсортировать по "дате, добавленной", имеют "дату, добавил" столбец.

Рассматривают их как яблоки и апельсины: имеет смысл спрашивать, совпадает ли яблоко с апельсином? Да. Имеет смысл спрашивать, больше ли яблоко, чем апельсин? Нет. (На самом деле это делает, но Вы понимаете мою мысль.)

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

58
ответ дан Tamas Czinege 24 November 2019 в 15:41
поделиться

Это не может проложить себе путь. Рассмотрите:

  • программа один, Вы открываете транзакцию и вставляете в таблицу FOO, которая имеет autoinc первичный ключ (произвольно, мы говорим, что это добирается 557 для его значения ключа).
  • Программа два запускается, она открывает транзакцию и вставляет в таблицу FOO, добираясь 558.
  • Программа два вставляет в таблицу BAR, которая имеет столбец, который является внешним ключом к НЕЧТО. Таким образом, теперь эти 558 расположены и в НЕЧТО и в ПАНЕЛИ.
  • Программа два теперь фиксации.
  • Программа три запускает и генерирует отчет от таблицы FOO. Эти 558 записей печатаются.
  • После этого, программа каждый откатывает.

, Как база данных исправляет эти 557 значений? Это входит в НЕЧТО и постепенно уменьшает все другие первичные ключи, больше, чем 557? Как это фиксирует ПАНЕЛЬ? Как это стирается, эти 558, распечатанные на программе отчета три, производят?

порядковые номера Oracle также независимы от транзакций по той же причине.

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

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

79
ответ дан jmucchiello 24 November 2019 в 15:41
поделиться

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

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

11
ответ дан Paul Lefebvre 24 November 2019 в 15:41
поделиться

Я не знаю ни о каком способе сделать это. Согласно MySQL Documentation , это - ожидаемое поведение и произойдет со всем режимы блокировки innodb_autoinc_lock_mode. Определенный текст:

Во всех режимах блокировки (0, 1, и 2), если транзакция, которая генерировала автоинкрементные значения, откатывает, те автоинкрементные значения являются “lost. ” Однажды значение сгенерирован для столбца автоприращения, он не может откатываться, завершается ли оператор “INSERT-like”, и откатывается ли содержание транзакции. Такие потерянные значения не снова используются. Таким образом могут быть разрывы в значениях, сохраненных в столбце AUTO_INCREMENT таблицы.

9
ответ дан gpojd 24 November 2019 в 15:41
поделиться

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

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

0
ответ дан tvanfosson 24 November 2019 в 15:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: