日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

01 前言

哈嘍,好久沒更新啦。因為最近在面試。用了兩周時間準備,在 3 天之內拿了 5 個 offer,最后選擇了廣州某互聯網行業獨角獸 offer,昨天剛入職。這幾天剛好整理下在面試中被問到有意思的問題,也借此機會跟大家分享下。

這家企業的面試官有點意思,一面是個同齡小哥,一起聊了兩個小時(聊到我嘴都干了)。他問了我一個有意(keng)思(b)問題:

數據庫中的自增 ID 用完了該怎么辦?

這個問題其實可以分為有主鍵 & 無主鍵兩種情況回答。

國際慣例,先上張腦圖:

面試官:數據庫自增 ID 用完了會咋樣?

 

1.1 往期精彩

MySQL 查詢語句是怎么執行的?

MySQL 索引

MySQL 日志

MySQL 事務與 MVCC

MySQL 的鎖機制

MySQL 字符串怎么設計索引?

02 有主鍵

如果你的表有主鍵,并且把主鍵設置為自增。

在 MySQL 中,一般會把主鍵設置成 int 型。而 MySQL 中 int 型占用 4 個字節,作為有符號位的話范圍就是 [-2^31,2^31-1],也就是 [-2147483648,2147483647];無符號位的話最大值就是 2^32-1,也就是 4294967295。

下面以有符號位創建一張表:

CREATE TABLE IF NOT EXISTS `t`(
   `id` INT(11) NOT NULL AUTO_INCREMENT,
   `url` VARCHAR(64) NOT NULL,
   PRIMARY KEY ( `id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

插入一個 id 為最大值 2147483647 的值,如下圖所示:

面試官:數據庫自增 ID 用完了會咋樣?

 

如果此時繼續下面的插入語句:

INSERT INTO t (url) VALUES ('wwww.JAVAfish.top/article/erwt/spring')

結果就會造成主鍵沖突:

面試官:數據庫自增 ID 用完了會咋樣?

 

2.1 解決方案

雖說 int 4 個字節,最大數據量能存儲 21 億。你可能會覺得這么大的容量,應該不至于用完。但是互聯網時代,每天都產生大量的數據,這是很有可能達到的。

所以,我們的解決方案是:把主鍵類型改為 bigint,也就是 8 個字節。這樣能存儲的最大數據量就是 2^64-1,我也數不清有多少了。反正在你有生之年應該是夠用的。

PS:單表 21 億的數據量顯然不現實,一般來說數據量達到 500 萬就該分表了

03 沒主鍵

另一種情況就是建表時沒設置主鍵。這種情況,InnoDB 會自動幫你創建一個不可見的、長度為 6 字節的 row_id,默認是無符號的,所以最大長度是 2^48-1。

實際上 InnoDB 維護了一個全局的 dictsys.row_id,所以未定義主鍵的表都共享該 row_id,并不是單表獨享。每次插入一條數據,都把全局 row_id 當成主鍵 id,然后全局 row_id 加 1。

這種情況的數據庫自增 ID 用完會發生什么呢?

1、創建一張無顯示設置主鍵的表 t:

CREATE TABLE IF NOT EXISTS `t`(
   `age` int(4) NOT NULL
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

2、通過 ps -ef|grep mysql 命令獲取 mysql 的進程 ID,然后執行命令,通過 gdb 先把 row_id 修改為 1。PS:沒有 gdb 的,百度安裝下

sudo gdb -p 16111 -ex 'p dict_sys->row_id=1' -batch

出現下圖就是沒錯的:

面試官:數據庫自增 ID 用完了會咋樣?

 

3、插入三條數據:

insert into t(age) values(1);
insert into t(age) values(2);
insert into t(age) values(3);

此時的數據庫數據:

面試官:數據庫自增 ID 用完了會咋樣?

 

4、gdb 把 row_id 修改為最大值:281474976710656

sudo gdb -p 16111 -ex 'p dict_sys->row_id=281474976710656' -batch

5、再插入三條數據:

insert into t(age) values(4);
insert into t(age) values(5);
insert into t(age) values(6);

此事的數據庫數據:

面試官:數據庫自增 ID 用完了會咋樣?

 

分析:

  • 剛開始設置 row_id 為 1,插入三條數據 1、2、3 的 row_id 也理應是 1、2、3;這是沒問題的。
  • 接著設置 row_id 為最大值,緊跟著插入三條數據。這時的數據庫結果是:4、5、6、3;你會發現 1、2 被覆蓋了。
  • row_id 達到后最大值后插入的值 4、5、6 的 row_id 分別是 0、1、2;由于 row_id 為 1、2 的值已存在,所以后者的值 5、6 會覆蓋掉 row_id 為 1、2 的值。

結論:row_id 達到最大值后會從 0 重新開始算;前面插入的數據就會被后插入的數據覆蓋,且不會報錯。

04 總結

數據庫自增主鍵用完后分兩種情況:

  • 有主鍵,報主鍵沖突
  • 無主鍵,InnDB 會自動生成一個全局的 row_id。它到達最大值后會從 0 開始算,遇到 row_id 一樣時,新數據覆蓋舊數據。所以,我們還是盡量給表設置主鍵

為什么我說這是個有意(keng)思(b)問題?

我的回答除了以上解決方法外,還提到在業務開發中,我們不會等到主鍵用完那天就已經分庫分表了,基本不會遇到這種情況。

這時,面試官可能會問你分庫分表咋處理,如果你不會就不要主動提了,點到即止。

05 參考文章

  • blog.csdn.net/weixin_39640090/article/details/113227742
  • blog.csdn.net/qq_35393693/article/details/100059966
  • time.geekbang.org/column/article/69862

原文鏈接:
https://mp.weixin.qq.com/s/1gmpJqBmCBsNPlLbrN0Q7Q

分享到:
標簽:數據庫
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定