Недавно я читал, что из-за того, как InnoDB пересчитывает значение AUTO_INCREMENT при перезапуске сервера, любые записи в верхнем конце списка идентификаторов могут повторно использоваться их идентификаторы.
Обычно это не проблема, поскольку при удалении пользователя все, что связано с идентификатором, удаляется и из других таблиц.
Но я намеренно оставляю их сообщения на форуме осиротевшими, помеченными как «Автор: = Пользователь # 123 =», так что прошлые разговоры сохраняются. Очевидно, что в случае повторного использования идентификатора это будет проблемой.
У меня никогда не было этой проблемы раньше, потому что всегда было достаточно новых пользователей, чтобы маловероятно, что идентификатор будет использован таким образом. Однако в моем новом проекте регистрации происходят редко, а неактивные удаления пользователей происходят часто (особенно потому, что учетные записи «Open Alpha» длятся только три дня в качестве предварительного просмотра), и такое повторное использование идентификаторов уже произошло три на три.
Я «исправил» проблему, сохранив правильное значение для AUTO_INCREMENT в другом месте и используя его вместо того, чтобы полагаться на внутреннее значение. Есть ли реальный способ, чтобы InnoDB запомнил фактическое последнее значение?
Ответы:
(избегая проблемы, никогда не удаляя)
Поскольку вы хотите сохранить
"Posted by =User #123="
информацию после удаления пользователяid=123
, вы также можете рассмотреть возможность использования двух таблиц для хранения данных пользователей. Один дляActive
пользователей и один для всех (включая удаленных из активных пользователей). И никогда не удаляйте эти идентификаторы изAllUser
таблицы:Это, конечно, усложнит операцию вставки нового пользователя. Любой новый пользователь будет означать 2 вставки, по одной в каждой таблице. Удаление пользователя будет происходить только путем удаления из
ActiveUser
таблицы. Все FK будут удалены каскадно, кроме сообщений на форуме, которые будут ссылаться наAlluser
таблицу (где удаление никогда не произойдет).источник
Нет естественного способа сделать это, кроме как использовать information_schema.tables для записи всех столбцов с опцией auto_increment.
Вы можете собрать эти столбцы следующим образом:
Создайте скрипт, который будет сбрасывать значения auto_increment
Затем вы можете сделать одну из двух вещей:
ВАРИАНТ №1: запускать скрипт вручную после запуска
ВАРИАНТ № 2: Пусть mysqld выполняет скрипт перед разрешением соединений
Вы должны добавить эту опцию
Таким образом, каждый раз, когда вы перезапускаете mysql, этот скрипт выполняется в начале. Перед выполнением запланированного перезапуска mysql вам придется помнить о регенерации /var/lib/mysql/ResetAutoInc.sql.
источник
В документации 5.5 предлагается хранить значение автоинкремента в другом месте, как у вас уже есть.
Альтернативным решением будет эмуляция SEQUENCE, чтобы вы не использовали автоинкремент в самой таблице. Это обсуждалось на SO до и снова . Блоге MySQL Performance упоминает о нем.
Еще одна ошибка в данных MySQL, которой нет в других СУБД ...
источник
Только не удаляйте пользователя. Относительная целостность важнее. Если вам нужно из-за соображений конфиденциальности или чего-то еще, просто измените имя пользователя на «удалено» и удалите все остальные поля.
источник
Это старый вопрос и по-прежнему актуален.
1) Это поведение исправлено в Mysql 8.0.
2) Одним из решений является использование фиктивной строки для ваших данных, чтобы значение AUTO_INCREMENT превышало определенное значение. Не очень удобно в зависимости от того, что вы храните, но в некоторых случаях это простое решение.
источник
Нам понадобилось это экстраполированное решение для нашей собственной системы, основанное на инструкциях на этом посте. Если это может помочь кому-то достичь своей цели еще более простым способом.
Наша система использует шаблон таблиц-надгробий для хранения удаленных элементов, потому что мы выполняем двухстороннюю синхронизацию на отключенных системах, поэтому мы используем этот код для сопоставления таблиц-надгробий с их действующими таблицами и извлечения максимально возможного значения :)
источник