前天有位朋友去面试,其中被面试官问了一个mysql面试题MySQL自增主键id用完了怎么办?他因为对这块知识了解不多,所以答的不太好。

本文就给大家分享下,MySQL自增主键达到上限后会发生什么?我们又该如何解决这种问题?

我们平常在创建MySQL表的时候,为了考虑到性能,通常都会用MySQL的自增主键id,每一个自增id都会有一个初始值,通常都是从1开始,然后每次插入数据时就不断增加步长(不配置的话步长默认为1)。

不过,大家有没有考虑过,其实咱们定义的int或者bigint的长度那都是有上限的。

如果表中的最大记录id超过这个上限值,MySQL会发生什么错误呢?

所有int类型的取值范围
所有int类型的取值范围

从上图我们可以知道,tinyint和smallint的取值范围都比较小,我们通常不会将其作为主键id的类型。

如果主键采用有符号int类型进行自增,那么id的最大值是2147483647,如果采用无符号int类型进行自增,那么id的最大值是4294967295。

以无符号int类型为例,42亿虽看似是个很大的数字,不过对一些插入删除非常频繁的业务来说,触达这个上限也是用不了多久的。

另外如果有的业务表设置的步长较大,就会导致id自增的速度更快。

MySQL自增主键达到上限后会发生什么问题或现象?

首先,我们可以来验证一下,当MySQL的自增主键达到最大值后,再继续往表中插数据会出现什么现象?

新建一张表,并且直接指定最大自增值为4294967295。

CREATE TABLE t_max( id int unsigned auto_increment PRIMARY KEY ) auto_increment = 4294967295;

执行几次以下插入数据的sql看看会出现什么结果。

INSERT t_max ( id ) VALUES ( NULL );

咱可以看到,mysql直接提示主键重复了。

这里我们也可以验证MySQL的主键策略:id自增值达到上限以后,再申请下一个 id 时,仍然是最大值。

所以,如果你的业务预期会产生很多数据,那么建议你在创建表时,直接使用bigint,无符号的bigint最大值是18446744073709551615,这个数基本可以保证你的业务不受影响了。

当然,如果主键需要对外展示,为了安全考虑,大家也可以采用雪花算法生成的主键值,雪花算法产生的值和bigint一样都占用8个字节,并且是大致递增的,对性能也不会产生影响。

另外补充几句,建表时采用什么类型的主键,还是要根据具体业务具体分析,合理的主键类型会占用更小的空间,具有更好的性能。毕竟bigint占用8个字节,比int多了一倍呢。

希望上面这道mysql面试题分析对你有帮助,记得我们的https://mysql360.com域名哦。