我叫小M畔裕,立志建立MySQL帝國衣撬。

我是小M,我在卡拉巴拉星球扮饶。

我喜歡數(shù)據(jù)淮韭,我立志成為一個(gè)數(shù)據(jù)管理者。

所以我來 Y 公司應(yīng)聘贴届,聽說他們的數(shù)據(jù)量挺大的。

面試過程還是挺簡單的。

我用 007 這三個(gè)數(shù)字就輕易打敗了一堆吹噓 996 的應(yīng)聘者毫蚓。

此刻占键,我獨(dú)領(lǐng)風(fēng)騷。

1

今天是我第一天上班元潘,我筆直地坐在工位上畔乙,等著老板的寵幸。

下午兩點(diǎn)翩概。

Y 老板推門而入牲距,打著哈欠看著我:“007,你背有問題钥庇?坐得這么直牍鞠?”

“老板你好,我叫小M评姨,不是叫 007 难述,007 是我對(duì)公司的熱愛,是我的畢生....”

“打住打住吐句,看到你前面辦公桌上十幾條數(shù)據(jù)了么胁后?”

“你的任務(wù)就是管理好它們,這些數(shù)據(jù)隨時(shí)會(huì)增加嗦枢、查閱攀芯、刪除、更新的哦文虏÷屡担”

我激動(dòng)著、顫抖著回答:“Yes择葡,Sir紧武!”

2

花了10分鐘的時(shí)間,我把桌上的數(shù)據(jù)都掃視了一遍敏储。

是的阻星,沒錯(cuò),就十幾條數(shù)據(jù)我花了十分鐘已添。

因?yàn)檫@是我的第一份工作妥箕,我熱愛!

這些數(shù)據(jù)都來自一個(gè)叫 User 的部門更舞,它們都有一樣的結(jié)構(gòu):

image

這堆數(shù)據(jù)的 ID 都是有規(guī)律的畦幢,我想著就按順序把它排排坐,我用鏈表將它們相連缆蝉。

image

每次查找數(shù)據(jù)宇葱,我從頭開始遍歷往后找就行了瘦真,有序,簡單黍瞧。

我真是個(gè)小天才诸尽。

就這樣日復(fù)一日,年復(fù)一年印颤,User 的數(shù)據(jù)在不斷的增加您机,現(xiàn)在已經(jīng)多達(dá)百條了。

image

這個(gè)鏈表也越來越長年局,每次老板來找我要數(shù)據(jù)际看,我查找的時(shí)間也越來越慢。

而且不僅是大老板矢否,我發(fā)現(xiàn)好多小老板也來找我要數(shù)據(jù)仲闽。

我快要累死了,我的腰漸漸地也直不起來了兴喂。

3

5月1號(hào)深夜蔼囊,今天是勞動(dòng)節(jié)。

我依舊在公司加班衣迷。

我想不能再這樣下去了畏鼓,是時(shí)候祭出我的秘密武器了!

只有在夜深人靜一個(gè)人的時(shí)候壶谒,我才能召喚它云矫!

螺螄粉!

image

沒錯(cuò)汗菜,就是它让禀!

因?yàn)槲野l(fā)現(xiàn),嗦了螺螄粉之后陨界,我的腦子特別清晰巡揍,思維特別地發(fā)散。

為此菌瘪,我還特意去醫(yī)院檢查了下腦子腮敌,醫(yī)生說從片子上看的話一切正常,不過從感覺上看我可能不太正常俏扩。

不管了糜工,反正我知道,螺螄粉確實(shí)能賦予我通透的頭腦录淡。

因?yàn)榘颇荆藭r(shí)我的腦子已經(jīng)開始動(dòng)起來了!

有了嫉戚!

我忽然回想起刨裆,在大學(xué)里面有一門叫《數(shù)據(jù)結(jié)構(gòu)》的課程里講了二分法澈圈。

現(xiàn)在有近一千條有序的數(shù)據(jù),我把它按每十條數(shù)據(jù)分為一組崔拥,于是我吭哧吭哧的一頓操作极舔。

image

(為了美觀,就畫10組)然后我再為每一組都配置一個(gè)链瓦,每個(gè)槽記錄了每組最大的那條記錄的地址
image

這樣盯桦,我就可以通過二分法快速查找記錄啦慈俯!

假設(shè)現(xiàn)在就10組數(shù)據(jù),然后我要找 ID 等于 12 這條數(shù)據(jù)拥峦,我就:

  1. 先計(jì)算中間槽的位置(1+10)/2=5贴膘,通過地址找到第五組,此時(shí)第五組ID是50略号,12<50刑峡,所以繼續(xù)二分。
  2. (1+5)/2=3玄柠,通過地址找到第三組突梦,此時(shí)第三組ID是30,12<30羽利,所以繼續(xù)二分宫患。
  3. (1+3)/2=2,通過地址找到第二組这弧,此時(shí)第二組ID是20娃闲,12<20,所以繼續(xù)二分匾浪。
  4. (1+2)/2=1皇帮,通過地址找到第一組,此時(shí)第一組ID是10蛋辈,12>10属拾,現(xiàn)在能斷定12在第二組。
  5. 從圖中看起來第一組和第二組是分開的梯浪?實(shí)際上地址是相連的捌年,所以通過第一組最后一條數(shù)據(jù),可以往后隨著單向鏈表遍歷挂洛,找到ID為12的這條數(shù)據(jù)礼预。

是不是很方便?

總結(jié)的來說:

  1. 先通過二分法找到數(shù)據(jù)所在的槽虏劲。
  2. 然后再通過單向鏈表遍歷得到數(shù)據(jù)托酸。

在數(shù)據(jù)量很大的時(shí)候這種查找方式非嘲保快速!

因?yàn)椴檎覕?shù)據(jù)的時(shí)間復(fù)雜度從O(n)幾乎簡化成了O(lgn)励堡!

我稱之為頁目錄谷丸,我可真是個(gè)小天才呢!

4

就這樣应结,日復(fù)一日刨疼,年復(fù)一年。

User 的數(shù)據(jù)量還在逐日增加鹅龄。

我發(fā)現(xiàn)每次查詢都需要掏出全部的名單來找揩慕。

我這小胳膊細(xì)腿的,都快抬不動(dòng)了扮休。

于是迎卤,在一個(gè)月黑風(fēng)高的夜晚,我又掏出了螺螄粉玷坠。

靈光乍現(xiàn)蜗搔!

image

我以一千個(gè)數(shù)據(jù)為一個(gè)界限來分割數(shù)據(jù),我將每一千個(gè)數(shù)據(jù)稱之為八堡。

沒錯(cuò)樟凄,我又想出了 idea,我將所有數(shù)據(jù)分為一頁一頁秕重,每頁之間用雙向鏈表相連不同。


圖圖圖圖圖圖

這樣每次查詢,我就不需要一次把有所數(shù)據(jù)都拉出來溶耘,我可以一頁一頁翻閱過去二拐。

當(dāng)然,頁內(nèi)部還是按照剛才那樣分組訪問凳兵。

現(xiàn)在我是這樣查找數(shù)據(jù)的:

  1. 每次查數(shù)據(jù)我從第一頁開始找百新。
  2. 然后按照頁內(nèi)查找的方式二分去查數(shù)據(jù),找不到就通過鏈表訪問下一頁庐扫。

因此饭望,訪問速度并沒有變快,只是每次不需要把數(shù)據(jù)全部撈出來形庭,只要一頁一頁的撈铅辞。

我的胳膊得到了解放。

5

公司越來越大萨醒,User 的數(shù)據(jù)爆炸性增長斟珊。

分的頁也越來越多,老板和小老板們開始抱怨了富纸。

老板說囤踩,“我讓你找個(gè)人旨椒,你找了1小時(shí)?你今年年終獎(jiǎng)還想不想要了堵漱!”

“唉综慎,那個(gè)人在最后一頁,我翻的要死才翻到勤庐,我太難了示惊!”

雖說在心里抱怨,但是我知道這樣下去不是辦法埃元。

頭可斷血可流涝涤,年終獎(jiǎng)不可少!

別問岛杀,問就是螺螄粉!

果不其然崭孤,螺螄粉是無敵的类嗤。

解決法子有了!

每個(gè)頁都標(biāo)上獨(dú)一無二的頁號(hào)辨宠。

參考書本目錄的設(shè)計(jì)遗锣,我還專門搞了一個(gè)頁,頁里面的存儲(chǔ)就是目錄嗤形!

我稱它為目錄頁精偿。

image

你看,這樣我就能通過這個(gè)目錄頁找到對(duì)應(yīng)的數(shù)據(jù)頁赋兵。

比如:我現(xiàn)在要找 ID 為 500 的那條數(shù)據(jù)笔咽。

  1. 我遍歷目錄頁數(shù)據(jù)就可以知道該條數(shù)據(jù)在頁1。
  2. 然后就開始在頁內(nèi)通過老套路二分來查找數(shù)據(jù)霹期!

可能有人覺得叶组,目錄頁也是有大小的呀!裝不下怎么辦历造?

沒事甩十,和數(shù)據(jù)頁一樣,新增頁唄吭产!


image

可能有人會(huì)問侣监,那目錄頁多了,查找目錄頁也會(huì)變慢的呀臣淤!

你說的沒錯(cuò)橄霉,但這可難不倒我這個(gè)小聰明!

我們可以再搞一級(jí)目錄荒典,我稱之為目中目(開個(gè)玩笑~)酪劫!


image

這樣吞鸭,每次我從根目錄開始查詢,只要幾次查詢我就能找到想要的數(shù)據(jù)覆糟!

我稱這整一個(gè)為索引吸耿!

image

Y 老板看到了我的設(shè)計(jì)之后,拍了拍我的腦袋肆资,“007磅崭,有一手啊,我看你這結(jié)構(gòu)看著像一棵樹麦箍,我這個(gè)人又喜歡吹牛 B漓藕,你看這玩意叫 B 樹怎么樣?”

“不行老板挟裂,我覺得這 B 格不夠高享钞,要么叫B+樹吧?”

“行啊诀蓉,007栗竖,年終獎(jiǎng)我提前發(fā)給你!”

“叮鈴渠啤,支付寶到賬狐肢,0.1元×げ埽”

我:“...........”

“對(duì)了 007 份名,這 User ID 太不好記了,下次我打算只告訴你名字妓美,讓你找僵腺。”

我內(nèi)心:“@#%^&%........”

故事未完部脚,敬請(qǐng)期待 ~


哈哈想邦,第一次寫這類故事,有點(diǎn)意思委刘。

這篇主要寫的是關(guān)于MySQL InnoDB 聚簇索引的設(shè)計(jì)丧没,闡述了 MySQL 的數(shù)據(jù)到底是如何查找的。

我記得之前阿里的面試官就問過我這個(gè)問題锡移,讓我說說數(shù)據(jù)在索引上是如何找到的呕童,越細(xì)越好。

嘿嘿淆珊,這下知道了吧夺饲。

不過,由于故事的原因,有些描述都是不準(zhǔn)確的往声,比如上面說的什么每一千條數(shù)據(jù)分為一頁擂找。

我下面統(tǒng)一更正一下并補(bǔ)充一些點(diǎn),看好了昂葡贯涎!

  • MySQL 一頁默認(rèn)16 KB,所以不是按數(shù)量的慢洋,是按總的記錄數(shù)所占的空間塘雳。
  • 頁內(nèi)記錄是單向鏈表連接,頁之間是雙向鏈表連接普筹。
  • 當(dāng)一頁數(shù)據(jù)存滿了之后需要進(jìn)行頁分裂败明,也就是拆分下記錄變成兩個(gè)頁。
  • 頁分裂操作也可能導(dǎo)致多個(gè)頁都滿了太防,比如你往一個(gè)頁中間插入數(shù)據(jù)妻顶,擠出一條數(shù)據(jù)到下一頁,然后下一頁也滿了蜒车,發(fā)生級(jí)聯(lián)盈包,影響性能,所以建議主鍵有序醇王,這樣不會(huì)往中間的頁插入數(shù)據(jù)
  • MySQL頁內(nèi)默認(rèn)會(huì)有一條最大記錄和一條最小記錄不存儲(chǔ)數(shù)據(jù)崭添,就是這樣設(shè)計(jì)的寓娩,和鏈表dummy節(jié)點(diǎn)類似。
  • 一頁除了存儲(chǔ)數(shù)據(jù)還有一些元數(shù)據(jù)呼渣,比如FileHeader棘伴、PageHeader等等,太細(xì)了講了你現(xiàn)在記得住屁置,過兩星期也記不住焊夸,我也一樣。
  • 一條記錄也有很多細(xì)節(jié)蓝角。

像大部分人可能知道 InnoDB B+樹索引的設(shè)計(jì)阱穗。

也能說出為什么要用 B+ 樹,但是很少會(huì)說到頁內(nèi)的二分查找使鹅。

其實(shí)這樣的設(shè)計(jì)很常見揪阶,像 Kafka 的索引也采用了二分,一般數(shù)據(jù)量大了患朱,數(shù)據(jù)有序的情況都會(huì)上二分鲁僚。

下次面試官問你,你就把這個(gè)跟他說說,面試官會(huì)覺得冰沙,嘖嘖真細(xì)啊侨艾。

對(duì)了,我上述講的只是索引結(jié)構(gòu)大致布局拓挥,想要看詳細(xì)的可以看《從根兒上理解 MySQL》唠梨,比如 FileHeader 有什么字段啊啥的。

不過撞叽,我個(gè)人覺得沒必要這么細(xì)姻成,反正記不住,精髓掌握的即可愿棋。

如果你喜歡這樣故事類的文章科展,可以留言讓我知道,我之后多往這方面寫糠雨。

image

我的個(gè)人github才睹,歡迎star!


我是yes甘邀,從一點(diǎn)點(diǎn)到億點(diǎn)點(diǎn)琅攘,我們下篇見

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末松邪,一起剝皮案震驚了整個(gè)濱河市坞琴,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌逗抑,老刑警劉巖剧辐,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異邮府,居然都是意外死亡荧关,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門褂傀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來忍啤,“玉大人,你說我怎么就攤上這事仙辟⊥ǎ” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵欺嗤,是天一觀的道長参萄。 經(jīng)常有香客問我,道長煎饼,這世上最難降的妖魔是什么讹挎? 我笑而不...
    開封第一講書人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任校赤,我火速辦了婚禮,結(jié)果婚禮上筒溃,老公的妹妹穿的比我還像新娘马篮。我一直安慰自己,他們只是感情好怜奖,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開白布浑测。 她就那樣靜靜地躺著,像睡著了一般歪玲。 火紅的嫁衣襯著肌膚如雪迁央。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評(píng)論 1 284
  • 那天滥崩,我揣著相機(jī)與錄音岖圈,去河邊找鬼。 笑死钙皮,一個(gè)胖子當(dāng)著我的面吹牛蜂科,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播短条,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼导匣,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了茸时?” 一聲冷哼從身側(cè)響起贡定,我...
    開封第一講書人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎可都,沒想到半個(gè)月后厕氨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡汹粤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了田晚。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嘱兼。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖贤徒,靈堂內(nèi)的尸體忽然破棺而出芹壕,到底是詐尸還是另有隱情,我是刑警寧澤接奈,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布踢涌,位于F島的核電站,受9級(jí)特大地震影響序宦,放射性物質(zhì)發(fā)生泄漏睁壁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望潘明。 院中可真熱鬧行剂,春花似錦、人聲如沸钳降。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽遂填。三九已至铲觉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間吓坚,已是汗流浹背撵幽。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留凌唬,地道東北人并齐。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像客税,于是被迫代替她去往敵國和親况褪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容