MySQL自增主鍵跳號問題

8563084發表於2020-12-24

出現場景:

在shell指令碼迴圈使用

insert 語句插入時候,

while((i<=3))

insert into a (select * from b where no=${i})

let "i++"


問題分析

原因: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

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69989885/viewspace-2745148/,如需轉載,請註明出處,否則將追究法律責任。

相關文章