✅MySQL自增主键用完了会怎么样?
典型回答
我们知道,在MySQL中,自增主键有两种,一种是显式的、一种是隐式的。如果我们在一张表中没有定义主键,那么,MySQL会创建一个隐藏的主键(row_id)作为主键。
那么,不管是我们自己定义的自增主键,还是row_id的这个主键,都是一个固定类型的,一般都是bigint unsigned,那么既然有固定类型,就有取值范围。那么随着数据量的增长,主键的值会不断增长,那么万一超过了这个范围限制,会怎么样呢?
如果是我们自己显式定义的一个自增ID,如果已经达到了上限,那么下一次申请ID的时候,得到的值就是那个最大值,后续也不会再增加。这时候我们会拿到一个已经用过的主键,如果继续插入的话,会报主键冲突。
那如果我们没有自定义自增ID,那么就会默认使用row_id,如果已经达到了上限,那么下一次申请ID的时候,得到的值会从0开始,然后继续重新自增。但是,这种情况如果我们因为没有设置主键,所以他不会报主键冲突,他会直接把这个row_id = 0的数据插入到数据库中,并且会把之前的row_id=0的数据给直接覆盖了。
所以,结论是:
- 显示自定义的自增ID,用完以后下次插入会报主键冲突。
- 未定义自增ID主键,会用row_id,用完以后下一次插入会覆盖历史数据。
那么,从这个方面来看的话,我们为了避免数据被覆盖,还是需要自己设置一个自增的主键ID的,毕竟异常我们是可以感知到的,但是数据覆盖我们可能过了很久才能发现。
扩展知识
真用完了咋办
MySQL中的自增主键用完是一个相对罕见的情况,但确实可能发生,尤其是在大数据量的应用中。
一旦用完了,可以有以下几个解决方式:
- 重用未使用的主键值(不推荐):
- 如果你的表中有删除操作,可能会有未使用的主键值。你可以通过编写脚本或程序来找到这些空缺,并在插入新行时显式地指定这些主键值。但这种方法可能会破坏数据的完整性和连续性。
- 归档旧数据(推荐):
- 如果表中的一些数据是历史数据,不再经常访问,可以将其归档到另一个表中,然后从原表中删除这些数据。这可以为新数据释放主键空间。
- 使用UUID作为主键(不推荐):
- 考虑使用 UUID(通用唯一标识符)作为主键。UUID 是128位长,几乎不可能用完。但这会增加存储需求,并可能影响性能。