MySQL INSERT INTO SELECT時自增Id不連續(xù)問題及解決
1.問題
最近筆者接到一個新的開發(fā)需求:
將多張相同字段的MySQL數(shù)據(jù)表合并為一張,一聽我就樂了,這不就是幾行INSERT INTO SELECT FROM…的事兒嘛。
在痛快的執(zhí)行完準(zhǔn)備交付的時候,發(fā)現(xiàn)了一個問題:
\qquad 合并好的數(shù)據(jù)表中的id居然不是連續(xù)自增的,也就是說合并的幾張數(shù)據(jù)表中每兩張表的Id中間沒有續(xù)上。
合并前的數(shù)據(jù)是長這樣的
合并好之后的數(shù)據(jù)是長這樣的
可以發(fā)現(xiàn)4下來就是8了,11下來是15
2.分析
通過仔細(xì)的研究之后發(fā)現(xiàn),對于批量插入數(shù)據(jù)語句,MySQL提供了批量申請自增id的策略:
- 語句執(zhí)行過程中,第一次申請自增id,會分配1個(2的0次方)
- 1個用完以后,這個語句第二次申請自增id,會分配2個(2的1次方)
- 2個用完以后,還是這個語句,第三次申請自增id,會分配4個(2的2次方)
也就是說當(dāng)我執(zhí)行下面這條語句時(user01一共四條數(shù)據(jù))
INSERT INTO user (name, age) SELECT name, age from user01;
- 第一次申請自增id會分配1個,1 < 4
- 第二次申請自增id會分配2個,1+2 < 4
- 第三次申請自增id會分配4個,1+2+4 > 4,終止
此時1 + 2 + 4 = 7 > 4,申請自增id的操作就會停止。
因為已經(jīng)申請了7個id了,所以當(dāng)我們執(zhí)行第二條SQL語句時,插入數(shù)據(jù)的id就會從8開始,此時AUTO_INCREMENT的值也會是8
3.解決方案
筆者采用的操作是在Navicat中修改自動遞增的值來保證它的id連續(xù):
直接將自動遞增的值刪除,然后保存
當(dāng)然,這個理論上是不能解決根本問題的。
4.結(jié)論
這么設(shè)計的主要原因是為了提升性能,所以自增id只保證是遞增的,但不保證是連續(xù)的!
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
MySQL 分表分庫怎么進(jìn)行數(shù)據(jù)切分
這篇文章主要介紹了MySQL 分表分庫怎么進(jìn)行數(shù)據(jù)切分,幫助大家更好的理解和學(xué)習(xí)使用MySQL,感興趣的朋友可以了解下2021-03-03深入解析MySQL的事務(wù)隔離及其對性能產(chǎn)生的影響
這篇文章主要介紹了MySQL的事務(wù)隔離及其對性能產(chǎn)生的影響,在MySQL的優(yōu)化方面具有一定的借鑒意義,需要的朋友可以參考下2015-12-12MySQL如何通過Navicat實現(xiàn)遠(yuǎn)程連接
這篇文章主要介紹了MySQL如何通過Navicat實現(xiàn)遠(yuǎn)程連接,幫助大家更好的理解和使用MySQL數(shù)據(jù)庫,感興趣的朋友可以了解下2020-09-09