MySQL的自增ID(主键) 用完了的解决方法
在MySQL中用很多类型的自增ID,每个自增ID都设置了初始值。一般情况下初始值都是从0开始,然后按照一定的步长增加(一般是自增1)。一般情况下,我们都是用int(11)来作为数据表的自增ID,在MySQL中只要定义了这个数的字节长度,那么就会有上限。
MySQL的自增ID(主键)用完了,怎么办?
如果用intunsigned(int,4个字节),我们可以算下最大当前声明的自增ID最大是多少,由于这里定义的是intunsigned,所以最大可以达到2的32幂次方-1=4294967295。
这里有个小技巧,可以在创建表的时候,直接声明AUTO_INCREMENT的初始值为4294967295。
createtable`test`( `id`int(10)unsignedNOTNULLAUTO_INCREMENT, PRIMARYKEY(`id`) )ENGINE=InnoDBAUTO_INCREMENT=4294967295;
SQL插入语句
insertinto`test`values(null);
当想再尝试插入一条数据时,得到了下面的异常结果。
[SQL]insertinto`test`values(null); [Err]1062-Duplicateentry'4294967295'forkey'PRIMARY'
说明,当再次插入时,使用的自增ID还是4294967295,报主键冲突的错误,这说明ID值达到上限之后,就不会再变化了。4294967295,这个数字已经可以应付大部分的场景了,如果你的服务会经常性的插入和删除数据的话,还是存在用完的风险,建议采用bigintunsigned,这个数字就大了。
bigintunsigned的范围是-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在代码实现上使用的是bigintunsigned类型,但实际上只给row_id留了6字节,这种设计就会存在一个问题:如果全局row_id一直涨,一直涨,直到2的48幂次-1时,这个时候再+1,row_id的低48位都为0,结果在插入新一行数据时,拿到的row_id就为0,存在主键冲突的可能性。
所以,为了避免这种隐患,每个表都需要定一个主键。
总结
数据库表的自增ID达到上限之后,再申请时它的值就不会在改变了,继续插入数据时会导致报主键冲突错误。因此在设计数据表时,尽量根据业务需求来选择合适的字段类型。
以上就是MySQL的自增ID(主键)用完了的解决方法的详细内容,更多关于MySQL自增ID(主键)的资料请关注毛票票其它相关文章!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。