出現(xiàn)場景:
在shell腳本循環(huán)使用
insert 語句插入時候,
while((i<=3))
insert into a (select * from b where no=${i})
let "i++"
我在插入的時候,就會出現(xiàn)id自增跳號問題,如下:
image.png
image.png
我的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執(zhí)行完了,事務(wù)提交,默認(rèn)自增id用到了15,所以下一組就是從16開始,如上圖:
然后在16的基礎(chǔ)上又開始分配了
也是成倍分配,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)結(jié)果也是從31開始
有人會問,那些斷層數(shù)據(jù)去哪里了?
那肯定是就可以看成被刪除了唄,你可以試一試,MySQL創(chuàng)建一個表,自增主鍵,比兔就用insert into values方法,插入1,2,3,4,然后刪除3,4,在插入數(shù)據(jù)肯定從5開始,不是3開始.
在批量插入,批量插入語句執(zhí)行過程中浦妄,申請策略:
1、第一次申請自增值時,會分配1個
2蕊唐、在N次申請自增值時性昭,會分配上一次(第N-1次)的2倍土全。
注意:上面出現(xiàn)id斷層在insert into a values這種方式不會出現(xiàn),因為他是逐條遞增
解決辦法:
在循環(huán)里面加上
alter table version_details AUTO_INCREMENT=1;
即每次執(zhí)行完一組insert into a(select * from b),
讓他回歸到該表目前存在的最大id
比如之前有一個表自增id值是1,2,3,4,人工刪除3,4,再往里面插數(shù)還是從5,開始,alter table version_details AUTO_INCREMENT=1;之后,再插數(shù)就從3開始了,另外這個alter table version_details AUTO_INCREMENT=1;可以不賦值1,只要是<=(當(dāng)前表中能看到的最大id+1)就行,如果你賦值1,MySQL自動幫你變道當(dāng)前表里存在的最大值+1