我正在做一些可能会出现的问题的研究。假设您有一个带有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列的值之间存在间隙,那么您仍然可以插入使用表中不存在的值的行,但必须id在INSERT查询中为其指定值。
无论如何,如果您的AUTO_INCREMENT列的类型是BIGINT您不必担心。
假设代码每秒插入一百万条记录(这被高估了,更不用说不可能了),那么id在接下来的一百万年中,该列有足够的值。或者292,277如果列不是,则仅数年UNSIGNED。
我目睹了一个实时Web服务器上的行为,该服务器使用INT(11)(而不是UNSIGNED)作为AUTO_INCREMENT一个表的ed PK,该表记录了有关该网站访问的信息。经过数年的平稳运行之后,当访问人数达到数十亿2^31(2甚至数十亿)时,它在深夜失败了。
从更改列类型INT来BIGINT是不是在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)