出现场景:
在shell脚本循环使用
insert 语句插入时候,
while((i<=3))
insert into a (select * from b where no=${i})
let "i++"
我在插入的时候,就会出现id自增跳号问题,如下:
我的id是自增主键 id int auto_increment
问题分析
原因:MySQL底层分配自增时候,注意是使用insert into a(select from b)
这种方式下是
成倍分配:1,2,4,8,16
(1),(2,3),(4,5,6,7),(8,9,10,11,12,13,14,15),
所以即使你没用到15,这组insert执行完了,事务提交,默认自增id用到了15,所以下一组就是从16开始,如上图:
然后在16的基础上又开始分配了
也是成倍分配,1,2,4,8,16
(16),(17,18),(19,20,21,22),(23,24,25,26,27,29,29,30)
即使没用到30,下一组insert into(select from)结果也是从31开始
有人会问,那些断层数据去哪里了?
那肯定是就可以看成被删除了呗,你可以试一试,MySQL创建一个表,自增主键,比兔就用insert into values方法,插入1,2,3,4,然后删除3,4,在插入数据肯定从5开始,不是3开始.
在批量插入,批量插入语句执行过程中,申请策略:
1、第一次申请自增值时,会分配1个
2、在N次申请自增值时,会分配上一次(第N-1次)的2倍。
注意:上面出现id断层在insert into a values这种方式不会出现,因为他是逐条递增
解决办法:
在循环里面加上
alter table version_details AUTO_INCREMENT=1;
即每次执行完一组insert into a(select * from b),
让他回归到该表目前存在的最大id
比如之前有一个表自增id值是1,2,3,4,人工删除3,4,再往里面插数还是从5,开始,alter table version_details AUTO_INCREMENT=1;之后,再插数就从3开始了,另外这个alter table version_details AUTO_INCREMENT=1;可以不赋值1,只要是<=(当前表中能看到的最大id+1)就行,如果你赋值1,MySQL自动帮你变道当前表里存在的最大值+1