MySQL遞增主鍵不連續(xù)的四種場景問題及解決
MySQL中可以設(shè)置auto_increment,作用是新增數(shù)據(jù)時(shí)不需要手動(dòng)添加主鍵,輸入null或未指定值時(shí)就會(huì)把a(bǔ)uto_increment的值賦給自增主鍵。
一般來說,自增主鍵都是連續(xù)的,但是,有四個(gè)場景自增主鍵不是連續(xù)的!(使用的是InnoDB引擎)

第一種、自增初始值和自增步長設(shè)置不為 1
InnoDB引擎有兩個(gè)屬性:auto_increment_offset(初始值)和auto_increment_increment(步長),一般默認(rèn)為1,即初始值1,每次自增1,所以子增值就是1,2,3,4,5...這就是連續(xù)的.
如果設(shè)置這兩個(gè)屬性,自增值就會(huì)從初始值開始,每次加一次步長得到下一個(gè)數(shù),比如設(shè)置初始值為3,步長為2,那自增值就是3,5,7,9...這就不是連續(xù)的了.
第二種、唯一鍵沖突
插入數(shù)據(jù)時(shí),如果有設(shè)置唯一的字段重復(fù)了,那么就會(huì)報(bào)錯(cuò),插入失敗,但此時(shí)系統(tǒng)的自增值還是會(huì)增加一次,這是由于insert語句的執(zhí)行流程導(dǎo)致的:
- 1.執(zhí)行器調(diào)用引擎準(zhǔn)備插入數(shù)據(jù)(null,1,1)
- 2.發(fā)現(xiàn)沒有主鍵值,獲取自增值2(表里已經(jīng)有數(shù)據(jù)1,1,1,假設(shè)第二個(gè)字段重復(fù))
- 3.將插入的數(shù)據(jù)改成(2,1,1)
- 4.自增值變?yōu)?
- 5.執(zhí)行插入操作,第二個(gè)字段重復(fù),報(bào) Duplicate key error,插入失敗
這個(gè)流程說明自增是在執(zhí)行插入數(shù)據(jù)之前,所以哪怕語句失敗了,自增值還是會(huì)自增,這時(shí)候再插入數(shù)據(jù)就會(huì)變成(3,2,1)了
第三種、事物回滾
MySQL里有個(gè)rollback,它是TCL語句,叫事務(wù)控制語句,比如commit和rollback,前者是提交,后者是回滾,作用是撤銷當(dāng)前事務(wù)中已經(jīng)進(jìn)行的所有修改,使數(shù)據(jù)庫返回到事務(wù)開始之前的狀態(tài)!
當(dāng)我們執(zhí)行了插入操作后,自增值會(huì)增加,此時(shí)我們回滾,數(shù)據(jù)會(huì)回到插入之前的數(shù)據(jù),但自增值不會(huì)跟著回到之前的自增值,這么設(shè)計(jì)的原因是為了提高性能.
因?yàn)槿绻藭r(shí)有多個(gè)并行執(zhí)行的事務(wù)(并行執(zhí)行時(shí)會(huì)加鎖),而回滾也會(huì)回滾自增值的話,就可能會(huì)導(dǎo)致主鍵重復(fù)沖突.為了解決這種沖突,要么就是判斷賦值自增值時(shí)表里是否已經(jīng)有此自增值,要么把鎖的范圍擴(kuò)大到一個(gè)事務(wù)執(zhí)行完并提交,無論是哪種方法,都會(huì)影響性能,所以才會(huì)設(shè)計(jì)自增值不會(huì)回滾。
第四種、批量插入
對于批量插入的數(shù)據(jù),MySQL有一個(gè)批量申請自增的策略:
- 第一次申請自增時(shí),會(huì)分配1個(gè)值
- 第二次時(shí),會(huì)分配2個(gè)值
- 第三次時(shí),會(huì)分配4個(gè)值
- ...
以此類推,同一個(gè)語句申請自增時(shí),每次申請的個(gè)數(shù)都是上一次的兩倍
(這里說的批量插入不是insert into table values(),這類語句是可以精準(zhǔn)計(jì)算出需要多少自增值的,不知道需要多少自增值的語句是insert...select、replace … select 和 load data)
舉個(gè)例子
有5個(gè)數(shù)據(jù)需要插入,(1,1),(2,2),(3,3),(4,4),(5,5)
- 第一次申請,申請一個(gè)id:1
- 第二次,申請兩個(gè)id:2,3
- 第三次,申請四個(gè)id:4,5,6,7
此時(shí)自增值就變成了8,下次插入數(shù)據(jù)時(shí)就會(huì)把8賦值給主鍵!
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
MySQL ClickHouse常用表引擎超詳細(xì)講解
這篇文章主要介紹了MySQL ClickHouse常用表引擎,ClickHouse表引擎中,CollapsingMergeTree和VersionedCollapsingMergeTree都能通過標(biāo)記位按規(guī)則折疊數(shù)據(jù),從而達(dá)到更新和刪除的效果2022-11-11
MYSQL必知必會(huì)讀書筆記第五章之排序檢索數(shù)據(jù)
本文給大家分享mysql必會(huì)必知讀書筆記第五章之排序檢索數(shù)據(jù),小編認(rèn)為非常具有參考價(jià)值,特此分享到腳本之家平臺供大家參考2016-05-05
phpstudy無法啟動(dòng)MySQL服務(wù)的完美解決辦法
學(xué)習(xí)php當(dāng)然是要先安裝好運(yùn)行環(huán)境了,phpstyudy是一個(gè)運(yùn)行php的集成環(huán)境,一鍵安裝對新手很友好,下面這篇文章主要給大家介紹了關(guān)于phpstudy無法啟動(dòng)MySQL服務(wù)的完美解決辦法,需要的朋友可以參考下2022-06-06
MySQL中查詢當(dāng)前時(shí)間間隔前1天的數(shù)據(jù)
實(shí)際項(xiàng)目中我們都會(huì)遇到分布式定時(shí)任務(wù)執(zhí)行的情況,今天通過本文給大家分享MySQL中查詢當(dāng)前時(shí)間間隔前1天的數(shù)據(jù),查詢sql語句給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧<BR>2021-12-12
MySql下關(guān)于時(shí)間范圍的between查詢方式
這篇文章主要介紹了MySql下關(guān)于時(shí)間范圍的between查詢方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07
MySQL執(zhí)行SQL文件報(bào)錯(cuò):Unknown collation ‘utf8mb4_0900_ai_
這篇文章主要給大家分享了MySQL執(zhí)行SQL文件出現(xiàn)【Unknown collation ‘utf8mb4_0900_ai_ci‘】的解決方案,如果又遇到相同問題的同學(xué),可以參考閱讀本文2023-09-09
MySQL在Windows中net start mysql 啟動(dòng)MySQL服務(wù)報(bào)錯(cuò) 發(fā)生系統(tǒng)錯(cuò)誤解決方案
這篇文章主要介紹了MySQL在Windows中net start mysql 啟動(dòng)MySQL服務(wù)報(bào)錯(cuò) 發(fā)生系統(tǒng)錯(cuò)誤解決方案,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
詳解標(biāo)準(zhǔn)mysql(x64) Windows版安裝過程
這篇文章主要介紹了標(biāo)準(zhǔn)mysql(x64) Windows版安裝過程,需要的朋友可以參考下2017-08-08

