面試官問:MySQL 的自增 ID 用完了,怎麼辦?

2020-10-16 Java進階架構師

★★★建議星標我們★★★

Java進階架構師星標」!這樣才不會錯過每日進階架構文章呀。

2020年Java原創面試題庫連載中

【000期】Java最全面試題庫思維導圖

【020期】JavaSE系列面試題匯總(共18篇)

【028期】JavaWeb系列面試題匯總(共10篇)

【042期】JavaEE系列面試題匯總(共13篇)

【049期】資料庫系列面試題匯總(共6篇)

【053期】中間件系列面試題匯總(共3篇)

【065期】數據結構與算法面試題匯總(共11篇)

【076期】分布式面試題匯總(共10篇)

【077期】綜合面試題系列(一)

【078期】綜合面試題系列(二)

【079期】綜合面試題系列(三)

【080期】綜合面試題系列(四)

【081期】綜合面試題系列(五)

【082期】綜合面試題系列(六)

【083期】綜合面試題系列(七)

【084期】綜合面試題系列(八)

【085期】綜合面試題系列(九)

【086期】綜合面試題系列(十)

【087期】綜合面試題系列(十一)

【088期】綜合面試題系列(十二)

【089期】綜合面試題系列(十三)

更多內容,點擊上面藍字查看

既然這塊知識點不清楚,那回頭就自己動手實踐下。

首先,創建一個最簡單的表,只包含一個自增 id,並插入一條數據。

create table t0(id int unsigned auto\_increment primary key) ;insert into t0 values;

通過 show 命令 show create table t0;查看表情況

CREATE TABLE \`t0\` ( \`id\` int(10) unsigned NOT AUTO\_INCREMENT, PRIMARY KEY (\`id\`)) ENGINE=InnoDB AUTO\_INCREMENT=2 DEFAULT CHARSET=utf8

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

這裡有個小技巧,可以在創建表的時候,直接聲明 AUTO_INCREMENT 的初始值

create table t1(id int unsigned auto\_increment primary key) auto\_increment = 4294967295;insert into t1 values;

同樣,通過 show 命令,查看 t1 的表結構

CREATE TABLE \`t1\` ( \`id\` int(10) unsigned NOT AUTO\_INCREMENT, PRIMARY KEY (\`id\`)) ENGINE=InnoDB AUTO\_INCREMENT=4294967295 DEFAULT CHARSET=utf8

可以發現,AUTO_INCREMENT 已經變成 4294967295 了,當想再嘗試插入一條數據時,得到了下面的異常結果

17:28:03 insert into t1 values Error Code: 1062. Duplicate entry '4294967295' for key 'PRIMARY' 0.00054 sec

說明,當再次插入時,使用的自增 ID 還是 4294967295,報主鍵衝突的錯誤。

4294967295,這個數字已經可以應付大部分的場景了,如果你的服務會經常性的插入和刪除數據的話,還是存在用完的風險,建議採用 bigint unsigned,這個數字就大了。

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

如果是這種情況,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,存在主鍵衝突的可能性。

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

來源:程序猿面試指南

之前,給大家發過三份Java面試寶典,這次新增了一份,目前總共是四份面試寶典,相信在跳槽前一個月按照面試寶典準備準備,基本沒大問題。

  • 《java面試寶典5.0》(初中級)

  • 《350道Java面試題:整理自100+公司》(中高級)

  • 《資深java面試寶典-視頻版》(資深)

  • 《Java[BAT]面試必備》(資深)

分別適用於初中級,中高級,資深級工程師的面試複習。

內容包含java基礎、javaweb、mysql性能優化、JVM、鎖、百萬並發、消息隊列,高性能緩存、反射、Spring全家桶原理、微服務、Zookeeper、數據結構、限流熔斷降級等等。

看到這裡,證明有所收穫

相關焦點

  • MySQL中的自增主鍵用完了怎麼辦?
    面試官:"用過mysql吧,你們是用自增主鍵還是UUID?面試官:"為什麼是自增主鍵?面試官:"那自增主鍵達到最大值了,用完了怎麼辦?"接下來,面試官可以問你一個更坑的問題!
  • 面試官問:MySQL 的自增 ID 用完了,怎麼辦?
    本文轉載自【微信公眾號:java進階架構師,ID:java_jiagoushi】經微信公眾號授權轉載,如需轉載與原文作者聯繫首先,創建一個最簡單的表,只包含一個自增 id,並插入一條數據。NOT NULL AUTO\_INCREMENT, PRIMARY KEY (\`id\`)) ENGINE=InnoDB AUTO\_INCREMENT=2 DEFAULT CHARSET=utf8可以發現 AUTO_INCREMENT 已經自動變成 2,這離用完還有很遠,我們可以算下最大當前聲明的自增 ID 最大是多少,由於這裡定義的是 intunsigned
  • MySQL表自增id用完了該怎麼辦?
    MySQL無符號整數上限為2^32 -1,即4294967295表的自增id用完了怎麼辦表定義的自增id達到了上線後,再申請下一個id時,得到的值保持不變。>PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=4294967295 DEFAULT CHARSET=utf8;上面創建了一張user表,id為自增主鍵,並且我們把AUTO_INCREMENT設置成了4294967295,也就是說下次執行insert語句的時候id為並且我們把
  • 面試官:資料庫自增ID用完了會怎麼樣?
    這些都是題外話,只是告訴你數據量大了是有可能達到上限的而已,回到Mysql自增ID上限的問題,可以分為兩個方面來說。1.有主鍵如果設置了主鍵,並且一般會把主鍵設置成自增。我們知道,Mysql裡int類型是4個字節,如果有符號位的話就是[-2^31,2^31-1],無符號位的話最大值就是2^32-1,也就是4294967295。
  • MySQL中的各種自增ID
    自增ID的數據類型我們在使用自增ID的時候,定義自增ID欄位的類型為int,而int類型是一個大類,它有可以細分為tinyint、smallint、mediumit、int、bigint5中類型。表自增主鍵的自增值如果一張表的自增ID用完之後,我們再次向這個表中插入數據會怎麼樣呢?我們使用tinyint類型的自增主鍵舉例舉例來實驗一下。
  • 【系統架構】MySQL的自增ID用完了,插入數據會出現什麼問題?
    數據表定義的自增 ID,如果達到上限之後。再申請下一個 ID 的時候,獲得到的值將保持不變。下面通過實驗來驗證一下:我們創建了一個表test,同時將自增id的初始值設置為4294967295,也就是假設現在自增id只剩下一個。
  • 面試官:什麼是大事務?小林哥:就是 很大...的...事務?
    小林你好,我是xxxxx面試官掃了下我的簡歷,發現了簡歷上的一點:熟悉mysql資料庫。這時候面試官笑了笑,仿佛心裡頭在盤算著後邊該怎麼問我這塊的知識點,我背地一涼。面試官聊聊你之前做的項目吧,看這上邊的經歷,似乎你寫的很多項目都是有用到過mysql資料庫啊。
  • MySQL 面試高頻 100 問,看完吊打面試官
    前一陣系統的學習了一下MySQL,也有一些實際操作經驗,偶然看到一篇和MySQL相關的面試文章,發現其中的一些問題自己也回答不好,雖然知識點大部分都知道,但是無法將知識串聯起來。因此決定搞一個MySQL靈魂100問,試著用回答問題的方式,讓自己對知識點的理解更加深入一點。
  • 月薪3W,面試官問:詳細聊聊MySQL中 聚簇、非聚簇索引和覆蓋索引
    今天我們聊聊:之前我去面試月薪30K中級開發,某公司CTO問我的問題。適合人群:想對MySQL原理有深入進階,面試想獲得更高薪資的同學。閱讀本篇需要你具備MySQL基礎知識。前言導讀:既然你點進來了,捂住手機試問你自己,會不會。如果會了就可以就此跳過,不要浪費時間,如果不會那麼你就花點心思好好看看吧。
  • 面試被問:JDBC底層是如何連接資料庫的?|sql|mysql|數據源|java|...
    背景  前兩天一個小夥伴面試的時候,被問JDBC底層是如何連接資料庫的?  他頓時一臉懵逼,因為大部分人只知道JDBC的幾個步驟,至於底層到底是怎麼連接資料庫的,還真不知道。  由於小夥伴是面試高級開發,問這種問題倒也不能說面試官過分,如果是初級或者中級,那問著問題就確實有些過分了。
  • Mysql 8新特性之(5):自增主鍵的bug已修復
    問題歷史背景是自增主鍵沒有持久化是個比較早的bug.MySQL5.7及以前版本MySQL伺服器重啟,會重新掃描表的主鍵最大值,如果之前已經刪除過id=100的數據,但是表中當前記錄的最大值如果是99,那麼經過掃描,下一條記錄的id是100,而不是101。
  • 9種分布式ID生成方式,騰訊面試官都懵了
    害怕一個主節點掛掉沒法用,那就做雙主模式集群,也就是兩個Mysql實例都能單獨的生產自增ID。那這樣還會有個問題,兩個MySQL實例的自增ID都從1開始,會生成重複的ID怎麼辦?等這批號段ID用完,再次向資料庫申請新號段,對max_id欄位做一次update操作,update max_id= max_id + step,update成功則說明新號段獲取成功,新的號段範圍是(max_id ,max_id
  • 面試官:如何添加新資料庫到MySQL主從複製環境?
    寫在前面今天,一名讀者反饋說:自己出去面試,被面試官一頓虐啊!為什麼呢?因為這名讀者面試的是某大廠的研發工程師,偏技術型的。所以,在面試過程中,面試官比較偏向於問技術型的問題。不過,技術終歸還是要服務於業務的,光會技術可不行,還要將技術應用於項目中才行。
  • 面試官問我:MySQL如何實現無數據插入,有數據更新?
    寫在前面馬上就是金九銀十的跳槽黃金期了,很多讀者都開始出去面試了。這不,又一名讀者出去面試被面試官問了一個MySQL的問題:向MySQL中插入數據,如何實現MySQL中沒有當前id標識的數據時插入數據,有當前id標識的數據時更新數據。其實,這題目一點也不難!!
  • 分布式ID生成策略,我和面試官掰扯了一個小時
    面試官又快速的掃了一下的簡歷,可能上次看過一次,都快過了一個多星期了,估計他都都忘了我的簡歷了吧。面試官:我看你簡歷上面寫著深入了解分布式,並且也做過分布式項目,挺好的,那你直到分布式項目中生成分布式ID的方法有哪些嗎?我:這個我知道,生成分布式ID的方法主要有以下幾種:資料庫自增ID。
  • 一口氣說出 9種 分布式ID生成方式,面試官有點懵了
    害怕一個主節點掛掉沒法用,那就做雙主模式集群,也就是兩個Mysql實例都能單獨的生產自增ID。那這樣還會有個問題,兩個MySQL實例的自增ID都從1開始,會生成重複的ID怎麼辦?:是一個樂觀鎖,每次都更新version,保證並發時數據的正確性idbiz_typemax_idstepversion1101100020000等這批號段ID用完,再次向資料庫申請新號段,對max_id欄位做一次update操作,update max_id= max_id + step,update成功則說明新號段獲取成功
  • 一口氣說出 9 種分布式 ID 生成方式,面試官有點懵了
    害怕一個主節點掛掉沒法用,那就做雙主模式集群,也就是兩個Mysql實例都能單獨的生產自增ID。那這樣還會有個問題,兩個MySQL實例的自增ID都從1開始,會生成重複的ID怎麼辦?增加第三臺MySQL實例需要人工修改一、二兩臺MySQL實例的起始值和步長,把第三臺機器的ID起始生成位置設定在比現有最大自增ID的位置遠一些,但必須在一、二兩臺MySQL實例ID還沒有增長到第三臺MySQL實例的起始ID值的時候,否則自增ID就要出現重複了,必要時可能還需要停機修改。
  • 一道經典的MySQL面試題,答案出現三次反轉
    面試風雲我們先來看下題目:一張表,裡面有ID自增主鍵,當insert了17條記錄之後,刪除了第15,16,17條記錄,再把MySQL重啟,再Insert一條記錄,這條記錄的ID是18還是15.這個題目的背景是不夠清晰的,這個表的存儲引擎沒有說是InnoDB還是MyISAM,所以存在不確定性,這麼說的意義在於,自增列的信息在MyISAM和InnoDB中的維護邏輯是不大一樣的,在MyISAM中是存儲持久化在文件中的,當資料庫重啟之後,是可以通過持久化的信息持續對ID進行自增的,而InnoDB的自增列信息既不在.frm文件,也不在.ibd文件中,所以在此啟動的時候會按照max(id
  • 面試被問:JDBC底層是如何連接資料庫的?
    背景前兩天一個小夥伴面試的時候,被問JDBC底層是如何連接資料庫的?他頓時一臉懵逼,因為大部分人只知道JDBC的幾個步驟,至於底層到底是怎麼連接資料庫的,還真不知道。由於小夥伴是面試高級開發,問這種問題倒也不能說面試官過分,如果是初級或者中級,那問著問題就確實有些過分了。
  • 為什麼MySQL不推薦使用uuid或者雪花id作為主鍵?
    前言在mysql中設計表的時候,mysql官方推薦不要使用uuid或者不連續不重複的雪花id(long形且唯一,單機遞增),而是推薦連續自增的主鍵id,官方的推薦是auto_increment,那麼為什麼不建議採用uuid,使用uuid究竟有什麼壞處?