圖靈學(xué)院Java架構(gòu)師-VIP-MySql索引底層數(shù)據(jù)結(jié)構(gòu)

MySql索引底層數(shù)據(jù)結(jié)構(gòu)

索引的本質(zhì)

索引是幫助MySQL高效獲取數(shù)據(jù)的排好序的數(shù)據(jù)結(jié)構(gòu)

很多文章都講過暗赶,Mysql底層的數(shù)據(jù)結(jié)構(gòu)是通過B+Tree實(shí)現(xiàn)的肛搬,那具體為什么要用這種結(jié)構(gòu)來實(shí)現(xiàn)呢禽笑?我們從各種數(shù)據(jù)結(jié)構(gòu)分析一下阎毅。假如數(shù)據(jù)庫中的數(shù)據(jù)是這個(gè)樣子的蜜笤。

1. 不用索引的方式查找

因?yàn)閿?shù)據(jù)是存在磁盤上的靴迫,所以如果想要查找表中col2 = 89的這條記錄惕味,則需要進(jìn)行6次的磁盤IO進(jìn)行查找,效率很低

2.二叉樹

比如給col2列中使用二叉樹的方式加入索引玉锌,結(jié)構(gòu)會(huì)變成這個(gè)樣子赦拘,此時(shí)我們想查找col2 = 22的這條記錄,利用二叉樹特性芬沉,右節(jié)點(diǎn)>父節(jié)點(diǎn)>左節(jié)點(diǎn)躺同。我們只需要進(jìn)行3次IO查找即可找到數(shù)據(jù)

二叉樹

看起來這種方式也不錯(cuò),但是如果我們是在col1中也使用這種方式存儲(chǔ)會(huì)是什么情況呢丸逸?下圖所示蹋艺,比如此時(shí)想查找col1 = 6的數(shù)據(jù),還是要進(jìn)行6次的磁盤IO黄刚,這樣的方式存儲(chǔ)就沒有什么用途了吧

二叉樹

3.紅黑樹

紅黑樹是二叉樹的一種捎谨,但它可以自動(dòng)對一棵樹進(jìn)行平衡,例如上圖中col1的情況,它將會(huì)用這種結(jié)構(gòu)存儲(chǔ)涛救,如圖畏邢。這種方式看來,應(yīng)該沒問題了吧检吆?但是想一想舒萎,表中數(shù)據(jù)如果有上百萬條記錄,那這個(gè)樹的高度會(huì)有多高蹭沛?樹的高度也就決定了磁盤IO的次數(shù)臂寝。為解決這個(gè)問題,是不是可以考慮減少樹的高度呢摊灭?下面介紹下B-Tree

紅黑樹

4.B Tree

圖中所示咆贬,B樹事實(shí)上是一種平衡的多叉查找樹,也就是說最多可以開m個(gè)叉(m>=2)我們稱之為m階b樹帚呼。

通過B Tree存儲(chǔ)結(jié)構(gòu)如下所示(假設(shè)是個(gè)4階B樹)掏缎。BTree是二叉樹的一種,所以也具有二叉樹的特點(diǎn)(右節(jié)點(diǎn)>父節(jié)點(diǎn)>左節(jié)點(diǎn))煤杀,此時(shí)眷蜈,比如我們想要查找20這個(gè)位置,則只需要進(jìn)行3次磁盤IO怜珍,即可定位到記錄。在mysql中凤粗,一排最多能存儲(chǔ)多少個(gè)呢酥泛?假設(shè)字段是BitInt類型(8字節(jié)),數(shù)據(jù)與數(shù)據(jù)之間存在指針空間(6字節(jié))嫌拣,假設(shè)表中數(shù)據(jù)一行大小為1kb柔袁。Mysql默認(rèn)存儲(chǔ)空間是16KB,由此可以得知异逐,如果用bigint類型存儲(chǔ)捶索,一排最多可以存儲(chǔ) 16*1024/(8+6+1024) ≈ 15個(gè)索引。假設(shè)一個(gè)高度為3的樹灰瞻,最多可以存儲(chǔ)多少個(gè)索引呢腥例? 15 * 15 * 15 = 3375。那有什么辦法能再次優(yōu)化呢酝润?我們來看下B+Tree的存儲(chǔ)結(jié)構(gòu)


5.B+Tree

B+Tree是B Tree的變種燎竖,形式上和BTree差不多,只是把數(shù)據(jù)做了一次冗余要销,所有的數(shù)據(jù)存在子節(jié)點(diǎn)上构回,如圖所示。通過這種冗余的方式,讓每一層中存儲(chǔ)的索引更多纤掸,假設(shè)表中的一行記錄需要1KB空間存儲(chǔ)脐供,一個(gè)高度為3的B+Tree最多可以支持多少索引數(shù)據(jù)?1170 * 1170 * 16 =?21,902,400借跪,由此可見政己,一個(gè)高度為3的B+Tree如果存滿的話,最多可以放2千萬條索引數(shù)據(jù)(因?yàn)閿?shù)據(jù)需要冗余垦梆,數(shù)值要小于計(jì)算出來的值匹颤,具體沒算),查詢時(shí)最多進(jìn)行3次磁盤IO即可定位到記錄托猩。

最下邊那個(gè)鏈表樣子的指針是做什么用的印蓖?范圍查詢(下圖中應(yīng)該是個(gè)雙向指針)。比如說我們想查找>15的索引對應(yīng)的數(shù)據(jù)京腥。如果按照BTree方式查找赦肃,需要不斷的返回父節(jié)點(diǎn)再次進(jìn)行查詢。而B+Tree通過這個(gè)鏈表指針公浪,直接獲取到下一個(gè)節(jié)點(diǎn)他宛。

6.Hash表

Mysql支持使用Hash方式建立索引,如圖欠气。我們都知道Hash算法是一種散列算法厅各,查找的時(shí)間復(fù)雜度為O(1),那這么好的辦法预柒,Mysql為什么默認(rèn)不使用Hash存儲(chǔ)索引呢队塘?答案是范圍查詢,如果是范圍查找宜鸯,Hash表的方式就搞不定了憔古,只能走全表查詢。所以如果表中的字段不需要用到范圍或條件查詢淋袖。那么用Hash結(jié)構(gòu)存儲(chǔ)則會(huì)快很多鸿市。


MyISAM 索引實(shí)現(xiàn)?

MyISAM 引擎使用 B+Tree 作為索引結(jié)構(gòu),葉節(jié)點(diǎn)的 data 域存放的是數(shù)據(jù)記錄的地址。下圖是 MyISAM 索引的原理圖即碗,MyISAM是非聚集索引焰情,索引和數(shù)據(jù)在磁盤中是分開存儲(chǔ)的,索引存儲(chǔ)的是磁盤位置剥懒。


InnoDB 索引實(shí)現(xiàn)?

在InnoDB 中,表數(shù)據(jù)文件本身就是按 B+Tree 組織的一個(gè)索引結(jié)構(gòu),這棵樹的葉點(diǎn)data 域保存了完整的數(shù)據(jù)記錄烙样。這個(gè)索引的 key 是數(shù)據(jù)表的主鍵,因此?InnoDB 表數(shù)據(jù)文件本身就是主索引。


InnoDB 與 MyISAM存儲(chǔ)數(shù)據(jù)方式是不同的蕊肥,MyISAM存的是磁盤地址谒获,而InnoDB主鍵索引存儲(chǔ)的是數(shù)據(jù)蛤肌,非主鍵索引存儲(chǔ)的是主鍵數(shù)值,這就是為什么 InnoDB 要求表中必須要有主鍵批狱,如果沒有顯式指定,則 MySQL系統(tǒng)會(huì)自動(dòng)選擇一個(gè)可以唯一標(biāo)識(shí)數(shù)據(jù)記錄的列作為主鍵,如果不存在這種列,則MySQL 自動(dòng)為 InnoDB 表生成一個(gè)隱含字段作為主鍵,類型為長整形裸准。

為什么推薦使用整型的自增主鍵?

因?yàn)槭褂肂+Tree結(jié)構(gòu)存儲(chǔ)赔硫,如果主鍵生成的沒有規(guī)律炒俱,在新增時(shí),會(huì)引發(fā)B+Tree分裂爪膊,影響效率权悟,如果是自增類型,僅改變末尾處的指針數(shù)據(jù)即可推盛。所以我們要避免使用uuid等這些字段作為表中的主鍵字段峦阁。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市耘成,隨后出現(xiàn)的幾起案子榔昔,更是在濱河造成了極大的恐慌,老刑警劉巖瘪菌,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件撒会,死亡現(xiàn)場離奇詭異,居然都是意外死亡师妙,警方通過查閱死者的電腦和手機(jī)诵肛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來默穴,“玉大人怔檩,你說我怎么就攤上這事”诙ィ” “怎么了珠洗?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵溜歪,是天一觀的道長若专。 經(jīng)常有香客問我,道長蝴猪,這世上最難降的妖魔是什么调衰? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮自阱,結(jié)果婚禮上嚎莉,老公的妹妹穿的比我還像新娘。我一直安慰自己沛豌,他們只是感情好趋箩,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布赃额。 她就那樣靜靜地躺著,像睡著了一般叫确。 火紅的嫁衣襯著肌膚如雪跳芳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天竹勉,我揣著相機(jī)與錄音飞盆,去河邊找鬼。 笑死次乓,一個(gè)胖子當(dāng)著我的面吹牛吓歇,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播票腰,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼城看,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了丧慈?” 一聲冷哼從身側(cè)響起析命,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎逃默,沒想到半個(gè)月后鹃愤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡完域,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年软吐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吟税。...
    茶點(diǎn)故事閱讀 38,599評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡凹耙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出肠仪,到底是詐尸還是另有隱情肖抱,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布异旧,位于F島的核電站意述,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏吮蛹。R本人自食惡果不足惜荤崇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望潮针。 院中可真熱鬧术荤,春花似錦、人聲如沸每篷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至子库,卻和暖如春枫笛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背刚照。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工刑巧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人无畔。 一個(gè)月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓啊楚,卻偏偏與公主長得像,于是被迫代替她去往敵國和親浑彰。 傳聞我的和親對象是個(gè)殘疾皇子恭理,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評論 2 348

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