Что происходит, когда заканчивается автоинкрементный столбец?

Рассмотрим простую таблицу со столбцом автоинкремента, подобную этой:

CREATE TABLE foo 
(
  `fooid` bigint unsigned NOT NULL auto_increment,
   ....snipped.... other columns
  PRIMARY KEY (`fooid`)
) 
ENGINE=InnoDB AUTO_INCREMENT=10

Как изменить дизайн так, чтобы мы не достигли максимума типа данных bigint? Диапазон без знака от 0 до 18446744073709551615. Я не знаю, сколько времени потребуется, чтобы достичь 18446744073709551615, но, как и в случае проблемы 2000 года, я хочу быть к этому готовым.

12.12.2008 07:28:08
3 ОТВЕТА
РЕШЕНИЕ

Предположим, вы вставляете одну строку каждую миллисекунду.

18446744073709551615 миллисекунд = 18446744073709552 секунд = 307445734561826 минут = 5124095576030 часов = 213503982335 дней = 584942417 лет

Так что это не совсем проблема Y2K

Вы можете вставить миллион строк в миллисекунду и все еще быть в порядке в течение более 500 лет.

Другими словами: не беспокойтесь об этом.

58
12.12.2008 07:34:01
Хорошо. Я не думаю, что мое приложение будет длиться так долго => 500 лет.
ashitaka 12.12.2008 07:40:46
Точно так же, если вы вставляете только один раз в секунду, ваше приложение будет работать в течение 68 лет с 32-битным подписанным int Сохраните 4 байта для каждой записи и используйте 32-битное int, если можете.
jmucchiello 12.12.2008 07:51:01
Я хотел бы знать, что произойдет, если вы используете меньший тип (например, INT), и он переполняется. Не стоит думать, что целое число фиксированного размера никогда не будет переполнено.
Joey Adams 13.10.2009 01:46:01
@Joey: Значит, вы меня опровергли, потому что я ответил на вопрос, который на самом деле задавали, вместо того, который вы бы задали себе? Странный. Почему бы не задать интересующий вас вопрос? Я думаю, что вполне разумно предположить, что целое число фиксированного размера никогда не переполнится, когда размер достаточно велик. Если вы начнете предполагать, что ваше приложение должно будет работать более 500 лет с миллионами обращений в миллисекунду в течение этого времени, вы почти наверняка собираетесь его переоценить.
Jon Skeet 13.10.2009 05:20:00
В далеком будущем люди выкопают это из Интернета и обвинят @JonSkeet во всех сбойных приложениях, потому что безответственные разработчики еще в 2008 году об этом не беспокоились: D
developerbmw 29.07.2015 02:52:17

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

В строгом режиме MySQL отклоняет значение, выходящее за пределы диапазона, выдает ошибку недопустимого значения и выдает ошибку INSERT. В нестрогом режиме по умолчанию MySQL уменьшает значение до максимально допустимого для типа данных и выполняет INSERT. Но происходит INSERTсбой, потому что AUTO_INCREMENTатрибут вызвал использование всех возможных значений, и вы получаете эту ошибку ( SMALLINTпример без знака ):

MySQL said:

#1062 - Duplicate entry '65535' for key 1

Для BIGINTприведенного здесь примера замените «65535» на 18 квинтиллионов, хотя вряд ли эта ошибка когда-либо возникала в рабочей базе данных.

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

18
13.12.2008 07:23:25

Не знаю о MySQL, но в случае Postgresql вы можете указать, является ли последовательность CYCLE / NO CYCLE. Если он создан с параметром CYCLE, он снова вернется к 1 (или к минимальному значению) и выдаст ошибку для дублированного ключа.

2
12.12.2008 11:08:02
Недоступно в MySQL.
Rick James 23.01.2016 23:05:30