MySQL的自增ID(主键)用完了的解决方法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
MySQL的⾃增ID(主键)⽤完了的解决⽅法
在 MySQL 中⽤很多类型的⾃增 ID,每个⾃增 ID 都设置了初始值。
⼀般情况下初始值都是从 0 开始,然后按照⼀定的步长增加(⼀般是⾃增 1)。
⼀般情况下,我们都是⽤int(11)来作为数据表的⾃增 ID,在 MySQL 中只要定义了这个数的字节长度,那么就会有上限。
MySQL的⾃增ID(主键) ⽤完了,怎么办?
如果⽤ int unsigned (int,4个字节 ), 我们可以算下最⼤当前声明的⾃增ID最⼤是多少,由于这⾥定义的是 int unsigned,所以最⼤可以达到2的32幂次⽅ - 1 = 4294967295。
这⾥有个⼩技巧,可以在创建表的时候,直接声明AUTO_INCREMENT的初始值为4294967295。
create table `test` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4294967295;
SQL插⼊语句
insert into `test` values (null);
当想再尝试插⼊⼀条数据时,得到了下⾯的异常结果。
[SQL] insert into `test` values (null);
[Err] 1062 - Duplicate entry '4294967295' for key 'PRIMARY'
说明,当再次插⼊时,使⽤的⾃增ID还是 4294967295,报主键冲突的错误,这说明 ID 值达到上限之后,就不会再变化了。
4294967295,这个数字已经可以应付⼤部分的场景了,如果你的服务会经常性的插⼊和删除数据的话,还是存在⽤完的风险,建议采⽤ bigint unsigned ,这个数字就⼤了。
bigint unsigned 的范围是 -2^63 (-9223372036854775808) 到 2^63-1 (9223372036854775807) 的整型数据(所有数字),存储⼤⼩为 8 个字节。
不过,还存在另⼀种情况,如果在创建表没有显⽰申明主键,会怎么办?
如果是这种情况,InnoDB会⾃动帮你创建⼀个不可见的、长度为6字节的row_id,⽽且InnoDB 维护了⼀个全局的dictsys.row_id,所以未定义主键的表都共享该row_id,每次插⼊⼀条数据,都把全局row_id当成主键id,然后全局row_id加1。
该全局row_id在代码实现上使⽤的是bigint unsigned类型,但实际上只给row_id留了6字节,这种设计就会存在⼀个问题:如果全局row_id⼀直涨,⼀直涨,直到2的48幂次-1时,这个时候再+1,row_id的低48位都为0,结果在插⼊新⼀⾏数据时,拿到的row_id就为0,存在主键冲突的可能性。
所以,为了避免这种隐患,每个表都需要定⼀个主键。
总结
数据库表的⾃增 ID 达到上限之后,再申请时它的值就不会在改变了,继续插⼊数据时会导致报主键冲突错误。
因此在设计数据表时,尽量根据业务需求来选择合适的字段类型。
以上就是MySQL的⾃增ID(主键) ⽤完了的解决⽅法的详细内容,更多关于MySQL ⾃增ID(主键)的资料请关注其它相关⽂章!。