Что происходит, когда я исчерпываю ключ, генерируемый bigint? Как с этим справиться? - программирование

Что происходит, когда я исчерпываю ключ, генерируемый bigint? Как с этим справиться?

Я не могу представить для себя хороший ответ для этого, поэтому я подумал спросить его здесь. На мой взгляд, мне всегда интересно, что произойдет, если исчерпан столбец AUTO INCREMENT PRIMARY ID в моей MySQL таблице?

Скажем, например, у меня есть таблица с двумя столбцами. ID (auto increment, primary, BIGINT unsigned) и DESC (VARCHAR 255). Я точно знаю, что BIGINT много, но он может достичь своего предела. Как мне обрабатывать сценарий, в котором в случае, если ID достигнет своего предела? Нужен ли мне другой сервер? Если тогда, как я могу его синхронизировать? Правильно ли это? Любые идеи друзей.

4b9b3361

Ответ 1

Это не закончится.

Максимальный размер: 9223372036854775807. При 1000 вставок/секунду, что 106751991167 дней стоит. Почти 300 миллионов лет, если моя математика права.

Даже если вы разделите его, используя смещения, где, скажем, 100 серверов имеют выделенный субдиапазон значений (x*100+0... x*100+99), вы не закончите. 10 000 машин, выполняющих 100 000 вставок в секунду, могут попасть туда примерно через три столетия. Конечно, это больше транзакций в секунду, чем Нью-Йоркская фондовая биржа, в течение сотен лет...

Если вы превысите ограничение на размер типа данных сгенерированного ключа, новые вставки не будут выполнены. В PostgreSQL (поскольку вы отметили этот PostgreSQL) с помощью bigserial вы увидите:

CREATE TABLE bigserialtest ( id bigserial primary key, dummy text );
SELECT setval('bigserialtest_id_seq', 9223372036854775807);
INSERT INTO bigserialtest ( dummy ) VALUES ('spam');

ERROR:  nextval: reached maximum value of sequence "bigserialtest_id_seq" (9223372036854775807)

Для обычного serial вы получите другую ошибку, потому что sequence всегда 64-бит, поэтому вы достигнете точки, где вам нужно изменить тип ключа на bigint или получить ошибка как:

regress=# SELECT setval('serialtest_id_seq', 2147483647);
regress=# INSERT INTO serialtest (dummy) VALUES ('ham');
ERROR:  integer out of range

Если вы действительно считаете, что ваш сайт может достигнуть предела в bigint в вашем приложении, вы можете использовать составной ключ - скажем (shard_id, subkey) - или ключ uuid.

Попытка справиться с этим в новом приложении - преждевременная оптимизация. Серьезно, из нового приложения для такого роста вы будете использовать ту же схему? Или двигатель базы данных? Или даже codebase?

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

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

См:

Серьезно, даже если вы построите следующий Gootwitfacegram, это не будет проблемой до того, как будет использована дата использования вашего третьего приложения...

Ответ 2

Большой int 2 ^ 63 или приблизительно 10 ^ 19. Тесты базы данных были все ярости несколько лет назад, используя стандартизованный Тест TPC-C

Как вы можете увидеть самый быстрый реляционный балл 30 000 000 (3x10 ^ 7 транзакций в минуту) для реляционной базы данных. Имейте в виду, что профиль будет включать в себя много чтений, и очень маловероятно, что одна и та же система может писать строки 30 000 000 в минуту.

Предполагая, что для исчерпания BigInt вам понадобится приблизительно 3x10 ^ 11 минут. В измерении времени мы поймем, что что-то вроде 6 миллионов лет

ERROR 1467 (HY000): Failed to read auto-increment value from storage engine

Если вы закончите работу, вы получите вышеуказанное сообщение об ошибке и перейдите к Guid для первичного ключа. 2 ^ 128, меньше цифровых бит на земле, чем это число (в четыре раза).

Ответ 3

Большие наборы данных не используют увеличивающиеся числа в качестве ключей. Не только потому, что у вас есть неявный верхний предел, но также создает проблемы, когда у вас несколько серверов; потому что вы рискуете иметь дубликаты первичных ключей, поскольку они являются инкрементальными.

Когда вы достигнете этого предела в MySQL, вы получите такую ​​загадочную ошибку, как это:

Error: Duplicate entry '0' for key 1

Лучше использовать уникальный идентификатор или какую-либо другую последовательность, которую вы создаете. MySQL не поддерживает последовательности, но postgresql делает.

Ответ 4

Как только автоинкремент достигнет предела для размера поля, INSERT генерируют ошибку.

На практике вы получите следующий тип ошибок:

ERROR 1467 (HY000): Failed to read auto-increment value from storage engine

Подробнее:

http://dev.mysql.com/doc/refman/5.1/en/example-auto-increment.html