MySQL 中 AUTO_INCREMENT 列达到最大值时会发生什么?

Sherwin.Wei Lv7

MySQL 中 AUTO_INCREMENT 列达到最大值时会发生什么?

回答重点

在 MySQL 中,如果表定义的自增 ID 到达上限后,再申请下一个 ID,得到的值不变! 因此会导致报重复值的错误。

扩展知识

自增 ID 上限实验

例如 int 是 4 个字节,上限是 2 的 32 次方 -1,即 2147483647,当到达这个值的之后,下次插入得到的还是这个值,来看一下实验:

1
2
3
4
5
6
create table mianshiya(
id int auto_increment primary key
) auto_increment=2147483647;
insert into mianshiya values(null);

insert into mianshiya values(null);

执行以上的 SQL,第一条 insert 成功插入数据,第二条则报重复值的错误!

image.png

实践出真知哈!

再列举下 AUTO_INCREMENT 列不同数据类型的最大值:

  • 对于 TINYINT(8位),最大值是 127(有符号)或 255(无符号)。
  • 对于 SMALLINT(16位),最大值是 32,767(有符号)或 65,535(无符号)。
  • 对于 MEDIUMINT(24位),最大值是 8,388,607(有符号)或 16,777,215(无符号)。
  • 对于 INT(32位),最大值是 2,147,483,647(有符号)或 4,294,967,295(无符号)。
  • 对于 BIGINT(64位),最大值是 9,223,372,036,854,775,807(有符号)或 18,446,744,073,709,551,615(无符号)。

如果 InnoDB 表没有配置主键,有最大值上限吗?

如果我们在 InnoDB 表中不配置主键,那么默认 InnoDB 会创建一个不可见的长度为 6 个字节的 row_id。

InnoDB 在全局维护了一个 dict_sys.row_id 值,所有需要用到 row_id 的表,每次插入一行数据,都会获取这个值,然后将其+1。

这个值的范围是 0~2^48-1。如果这个值达到上限后,又会从 0 开始,然后继续循环。如果插入的新数据的 row_id 在表中已存在,那么老的数据会被这个新数据覆盖,不会产生有任何报错。

如果要验证这个情况,可以通过 gbd 动态地将 mysql 的 dict_sys.row_id 修改,执行多次插入就能发现覆盖的问题。

一般生产环境中不会有表没有设置主键的情况,这个仅做了解即可。

Comments