如果自动增加值达到极限,该怎么办?

4 mysql auto-increment bigint

我正在做一些可能会出现的问题的研究。假设您有一个带有id和名称字段的InnoDB MySQL表。id字段具有BIGINT(20),并且为AUTO_INCREMENT加上其主键。

如果此表已满,您该怎么办,这意味着我们已达到ID的限制,并且无法再生成自动递增编号。

axi*_*iac 10

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

CREATE TABLE `tbl` (
    `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
    PRIMARY KEY (`id`)
);
Run Code Online (Sandbox Code Playgroud)

INSERT类似的查询:

INSERT INTO tbl(id) VALUES (NULL);
Run Code Online (Sandbox Code Playgroud)

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

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

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

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


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

假设代码每秒插入一百万条记录(这被高估了,更不用说不可能了),那么id在接下来的一百万年中,该列有足够的值。或者292,277如果列不是,则仅数年UNSIGNED


我目睹了一个实时Web服务器上的行为,该服务器使用INT(11)(而不是UNSIGNED)作为AUTO_INCREMENT一个表的ed PK,该表记录了有关该网站访问的信息。经过数年的平稳运行之后,当访问人数达到数十亿2^312甚至数十亿)时,它在深夜失败了。

从更改列类型INTBIGINT是不是在2十亿记录表中的溶液(它需要年龄来完成,当系统是活的,从来就没有足够的时间)。解决方案是创建一个新表,该表具有相同的结构,但BIGINT用于PK列,并具有该列的初始值AUTO_INCREMENT,然后切换表:

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`;
Run Code Online (Sandbox Code Playgroud)