如果自动增量值达到极限怎么办?

时间:2017-09-22 13:00:09

标签: mysql auto-increment bigint

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

如果此表已满,您会怎么做,这意味着我们已达到id的限制,并且不再生成自动增量编号。

2 个答案:

答案 0 :(得分:5)

我们假设一个表格结构如下:

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

INSERT查询如下:

INSERT INTO tbl(id) VALUES (NULL);

在实际代码中,表中还有其他列,它们也存在于INSERT查询中,但我们可以放心地忽略它们,因为它们不会为此特定问题带来任何价值。

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

  

SQL错误(167):列'id'超出范围值。

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

无论如何,如果INSERT列的类型为AUTO_INCREMENT,您无需担心。

假设代码每秒插入一百万条记录(这是高度高估的,不能说不可能),BIGINT列的值足够用于下一个half of million years }。如果列不是id,则只需292,277年。

我目睹了使用UNSIGNED(而不是INT(11))作为UNSIGNED ed PK的实时网络服务器上的行为,该表记录了有关网络访问的信息现场。经过几年的顺利运行,当访问次数达到AUTO_INCREMENT2^31十亿次等等)时,它在半夜失败了。

将列类型从2更改为INT不是20亿条记录表的解决方案(完成时间需要很长时间,当系统处于活动状态时,永远不会有足够的时间)。解决方案是创建一个具有相同结构的新表,但PK列为BIGINTBIGINT列为初始值,然后切换表:

AUTO_INCREMENT

答案 1 :(得分:2)

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)

您认为这个数字是一个小数字吗? 也许在你达到这个数字之前你会死的