自增值达到上限怎么办?

What to do if the auto-increment value reaches its limit?

我正在研究某天可能会出现的问题。 假设你有一个 InnoDB MySQL table 带有一个 id 和一个 name 字段。 id 字段有 BIGINT(20) 并且是 AUTO_INCREMENT 加上它的主键。

如果这个 table 已满,这意味着我们已经达到了 id 的限制,并且无法再生成自动递增编号,您会怎么做。

tinyint: 1 byte, -128 to +127 / 0 to 255 (unsigned)
smallint: 2 bytes, -32,768 to +32,767 / 0 to 65,535 (unsigned)
mediumint: 3 bytes, -8,388,608 to 8,388,607 / 0 to 16,777,215 (unsigned)
int/integer: 4 bytes, -2,147,483,648 to +2,147,483,647 / 0 to 4,294,967,295 (unsigned)
bigint: 8 bytes, -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 / 0 to 18,446,744,073,709,551,615 (unsigned)

你是不是觉得这个数字很小? 也许你在达到这个数字之前就已经死了

让我们假设一个 table 结构如下:

CREATE TABLE `tbl` (
    `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
    PRIMARY KEY (`id`)
);

INSERT 查询如:

INSERT INTO tbl(id) VALUES (NULL);

在实际代码中 table 中还有其他列,它们也出现在 INSERT 查询中,但我们可以安全地忽略它们,因为它们不会为此带来任何价值具体问题。

当列 id 的值达到最大值时,无法使用上述查询在 table 中插入更多行。下一个 INSERT 失败并显示错误:

SQL Error (167): Out of range value for column 'id'.

如果 id 列的值存在间隙,那么您仍然可以插入使用 table 中不存在的值的行,但您必须指定 id 的值] 在 INSERT 查询中。


无论如何,如果您的 AUTO_INCREMENT 列的类型是 BIGINT,您就不必担心。

假设代码每秒插入 一百万条记录(这被高估了,不能说不可能),id 列的值足够下一个 half of million years。或者如果该列不是 UNSIGNED.

,则只是 292,277

我目睹了使用 INT(11)(而不是 UNSIGNED)作为 AUTO_INCREMENTed PK 记录信息的 table 的实时网络服务器上的行为关于网站的访问。半夜失败了,经过几年运行的顺利,当访问量达到2^312亿什么的)。

将列类型从 INT 更改为 BIGINT 不是针对 20 亿条记录的解决方案 table(需要很长时间才能完成,当系统上线时,那里时间永远不够)。解决方案是创建一个具有相同结构但 PK 列为 BIGINTAUTO_INCREMENT 列为初始值的新 table,然后切换 table:

CREATE TABLE `tbl_new` (
    `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
    PRIMARY KEY (`id`)
) AUTO_INCREMENT=2200000000;

RENAME TABLE `tbl` TO `tbl_old`, `tbl_new` TO `tbl`;