MySQL的自增ID用完了怎麼辦???

以前就有過這樣的疑問,最近在學習MySQL這一塊,突然又想到了這個問題,就自己動手實驗了一下,請看過程。

先創建一張簡單的表,插入一條數據

create table test(id int unsigned auto_increment primary key);
insert into test values(null);

查看一下表情況,

show create table test

我們發現 AUTO_INCREMENT 已經自動變成2,這離用完還有很遠,我們可以算下最大當前聲明的自增ID最大是多少,由於這裏定義的是 intunsigned,所以最大可以達到2^32 - 1 = 4294967295 

 

所以我們改一下,在創建表的時候,直接聲明AUTO_INCREMENT的初始值。

create table t1(id int unsigned auto_increment primary key) auto_increment = 4294967295;

再查看一下,可以發現,AUTO_INCREMENT已經變成4294967295

再插入一條數據   insert into t1 values(null);

再次插入數據的時候,拿到的數據還是4294967295,因爲這條數據在數據庫中已經存在,所以就會報主鍵衝突的錯誤。4294967295,這個數字已經可以應付大部分的場景了,如果你的服務會經常性的插入和刪除數據的話,還是存在用完的風險,建議採用bigint unsigned,這個數字就大了。

不過,還存在另一種情況,如果在創建表沒有顯示申明主鍵,會怎麼辦?

如果是這種情況,

首先:如果表沒有顯示聲明主鍵,會先查看錶中有沒有唯一鍵值列(即某一列被unique修飾),如果有,則不會創建row_id,而是默認以這種列爲主鍵,如果沒有才會創建row_id。

InnoDB會自動幫你創建一個不可見的、長度爲6字節的row_id,而且InnoDB 維護了一個全局的 dictsys.row_id,所以未定義主鍵的表都共享該row_id,每次插入一條數據,都把全局row_id當成主鍵id,然後全局row_id加1

該全局row_id在代碼實現上使用的是bigint unsigned類型,但實際上只給row_id留了6字節,這種設計就會存在一個問題:如果全局row_id一直漲,一直漲,直到2的48冪次-1時,這個時候再+1,row_id的低48位都爲0,結果在插入新一行數據時,拿到的row_id就爲0,存在主鍵衝突的可能性。

所以,爲了避免這種隱患,每個表都需要定一個主鍵。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章