成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

InnoDB存儲引擎表的數(shù)據(jù)結(jié)構(gòu)

IT那活兒 / 3449人閱讀
InnoDB存儲引擎表的數(shù)據(jù)結(jié)構(gòu)




前  言 




數(shù)據(jù)的底層存儲上,InnoDB會根據(jù)每張表的主鍵構(gòu)造一棵B+樹,也就是說表中所有的數(shù)據(jù)都是存儲在B+樹中的。因此,InnoDB存儲引擎表也被稱為索引組織表。本篇文章會講解何為B+樹,以及InnoDB存儲引擎以B+樹結(jié)構(gòu)構(gòu)建的聚集索引和二級索引。


一. 底層存儲的數(shù)據(jù)模型——B+樹

1. B+樹簡介

B+樹是由B樹演化而來,不同于B樹適合在內(nèi)存中遍歷訪問,B+樹十分適合于在磁盤中存儲與讀取。從嚴(yán)格意義上講,B+樹已不滿足“樹”的定義。B+樹的定義這里不再詳細(xì)介紹,這里只介紹B+樹的幾個重要特點。如下圖所示,即是一棵B+樹。

  • 每個結(jié)點可以存儲多個關(guān)鍵字,且每個結(jié)點可以有多于兩個的孩子數(shù);

  • 所有葉子結(jié)點都位于同一層次;

  • 有分支結(jié)點中的關(guān)鍵字會在葉子結(jié)點中再次列出,也就是說葉子結(jié)點中包含全部關(guān)鍵字的信息;

  • 葉子結(jié)點之間通過雙向鏈表鏈接,即每個葉子結(jié)點都有指向上一個和下一個葉子結(jié)點的指針;

  • 葉子結(jié)點之間依關(guān)鍵字的大小自小而大鏈接。

2. B+樹為何適合于在磁盤中存儲與讀取

B+樹更適合于在磁盤中存儲與讀取,主要體現(xiàn)在其具有高扇出性和范圍查詢的高效率上。

  • 高扇出性:

扇出,是指上級模塊直接調(diào)用的下級模塊的數(shù)量)

對于一棵3層的1000階B+樹(結(jié)點最大的孩子數(shù)目稱為B+樹的階),可以存儲1000的3次方個值,也就是10億個值,這已經(jīng)可以滿足生產(chǎn)環(huán)境中大多數(shù)InnoDB表的存儲需求。

高扇出性帶來的好處就是查詢效率的提升,比如3層的B+樹,查詢某個關(guān)鍵字只需要3次IO,再考慮到一般情況下,根結(jié)點總會緩存在內(nèi)存中,所以只需要2次IO即可。當(dāng)前一般的機械硬盤每秒可以做100次IO,所以本次查詢花費的時間僅有0.02秒。

  • 范圍查詢:

傳統(tǒng)的二叉樹需要通過前序遍歷或其他遍歷方法來查詢所有結(jié)點中的關(guān)鍵字,而不同于二叉樹,B+樹所有的關(guān)鍵字都按照大小順序保存在葉子結(jié)點中,且通過雙向鏈表鏈接。因此針對范圍查詢,只需要從第一個匹配的關(guān)鍵字,通過鏈表繼續(xù)向下匹配即可。


二. 聚集索引與二級索引

InnoDB表在底層存儲上就是一棵棵的B+樹,每張表可能對應(yīng)多棵B+樹。首先,表中的數(shù)據(jù)會按照主鍵的順序構(gòu)造一棵B+樹,表中每行的數(shù)據(jù)都存儲在葉子結(jié)點中,這棵B+樹就是聚集索引。也因此,InnoDB表也被稱為索引組織表,數(shù)據(jù)即索引。除此之外,表中可能還有二級索引(也叫輔助索引),其在底層存儲上也是一棵B+樹。

1. 聚集索引

如下圖所示,即是聚集索引對應(yīng)的B+樹。其中數(shù)字代表每行數(shù)據(jù)的主鍵值,而葉子結(jié)點中的“ROW8”等代表具體的行數(shù)據(jù)。

如圖中所示,非葉子結(jié)點中存放的只有主鍵值以及指向葉子結(jié)點的指針,而葉子結(jié)點中存放的是主鍵值、行數(shù)據(jù)(包含所有字段的值,此處不考慮行溢出數(shù)據(jù))和指向上一個葉子結(jié)點與下一個葉子結(jié)點的指針。

葉子結(jié)點對應(yīng)著數(shù)據(jù)庫概念中的數(shù)據(jù)頁,在InnoDB存儲引擎中,每個數(shù)據(jù)頁大小默認(rèn)為16KB(innodb_page_size)。如圖中所示,每個數(shù)據(jù)頁中包含多行數(shù)據(jù),且按照主鍵的大小順序排列,也就是說,InnoDB表是天然排過序的。

2. 二級索引

如下圖所示,即是某個二級索引(輔助索引)對應(yīng)的B+樹。其中字母代表每行數(shù)據(jù)中的輔助索引值(非主鍵值),其中數(shù)字代表每行數(shù)據(jù)中的主鍵值。

如圖中所示,二級索引的非葉子結(jié)點中僅包含二級索引所在字段的值和指向葉子結(jié)點的指針,而葉子結(jié)點中包含二級索引值、主鍵值以及指向上一個葉子結(jié)點與下一個葉子結(jié)點的指針。正因為葉子結(jié)點中不包含整行數(shù)據(jù),當(dāng)需要通過二級索引查詢整行數(shù)據(jù)時,需要通過在二級索引中查詢到的主鍵值,回到聚集索引中再查詢一次,這個過程就被稱為“回表”。

在InnoDB中,每個索引都對應(yīng)一棵B+樹(聯(lián)合索引算一個索引),所以每張表至少包含一棵B+樹(聚集索引)。另外,B+樹是要占用磁盤空間的,所以單張表的索引不能定義太多,否則會造成磁盤空間的浪費。



延  伸 



通過本篇文章你應(yīng)該能了解到InnoDB表的底層存儲是一棵棵的B+樹,同時,你也應(yīng)該能意識到為什么必須設(shè)置主鍵?為什么創(chuàng)建索引會耗時比較久?當(dāng)某張表上索引特別多時,為什么Insert語句會執(zhí)行比較慢?為什么覆蓋索引效率會比較高?

1. 為什么必須設(shè)置主鍵?

InnoDB表是索引組織表,是通過聚集索引組織數(shù)據(jù)的,如果建表時定義了主鍵,InnoDB引擎就會選擇主鍵作為聚集索引,如果沒有定義主鍵,InnoDB引擎就會選擇第一個非空(不包含NULL)唯一索引作為聚集索引。如果以上條件都不滿足,InnoDB引擎會選擇內(nèi)置6字節(jié)的ROWID作為隱含的聚集索引。

另外可以發(fā)現(xiàn),當(dāng)主鍵值的長度越小,輔助索引占用的空間也會越小,這是因為輔助索引中并不存儲整行的數(shù)據(jù),而是只存儲該行數(shù)據(jù)的主鍵值。所以一般情況下都會使用自增主鍵。

2. 為什么創(chuàng)建索引耗時久?

因為創(chuàng)建輔助索引時就是憑空生成一棵B+樹,還要根據(jù)索引值重新組織數(shù)據(jù)的排列順序;當(dāng)創(chuàng)建主鍵索引時,則相當(dāng)于重新構(gòu)建聚集索引所在的B+樹。也因為創(chuàng)建索引的成本很高,所以最好在建表的時候就規(guī)劃好索引。

3. 當(dāng)表中索引特別多時,為什么Insert語句會執(zhí)行比較慢?

因為數(shù)據(jù)不僅會插入聚集索引所在的B+樹,還會在該表其余所有索引所在B+樹上插入數(shù)據(jù)(B+樹為了保持平衡,插入操作可能涉及到葉子結(jié)點的旋轉(zhuǎn)、拆分等操作)。在生產(chǎn)環(huán)境中,DBA一般都會制定開發(fā)規(guī)范,例如單張表上創(chuàng)建的索引數(shù)不得超過5個。

4. 為什么覆蓋索引效率會比較高?

前文中介紹了“回表”的概念,而“覆蓋索引”效率高就體現(xiàn)在其避免了“回表”的操作?!案采w索引”指從輔助索引中即可查到指定的字段,也可簡單理解為某個輔助索引中包含了所有待查詢的字段。輔助索引至少包含了兩個字段的值,輔助索引值以及其所在行的主鍵值,而聯(lián)合索引中包含的字段值會更多。

另外由于輔助索引中并不包含整行的數(shù)據(jù),所以其大小也要遠(yuǎn)小于聚集索引,因此可以減少大量的IO操作。在查詢時巧用覆蓋索引,可以讓查詢更加高效。


END


更多精彩干貨分享

點擊下方名片關(guān)注

IT那活兒

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/129857.html

相關(guān)文章

  • 搞定PHP面試 - MySQL基礎(chǔ)知識點整理 - 存儲引擎

    摘要:支持崩潰后的安全恢復(fù)。的使用場景更新密集的表存儲引擎特別適合處理多重并發(fā)的更新請求。外鍵約束支持外鍵的存儲引擎只有。引擎是及之前版本的默認(rèn)存儲引擎。文件存儲表的索引。引擎存儲引擎是引擎的變種。 MySQL基礎(chǔ)知識點整理 - 存儲引擎 0. 查看 MySQL 支持的存儲引擎 可以在 mysql 客戶端中,使用 show engines; 命令可以查看MySQL支持的引擎: mysql> ...

    whatsns 評論0 收藏0
  • 有趣的 Mysql 存儲引擎

    摘要:提供了一套統(tǒng)一的應(yīng)用開發(fā)模型和核心,因此,盡管不同的存儲引擎擁有不同的特性,不過對于開發(fā)人員,應(yīng)用操作都是完全透明的。 Mysql 提供了一套統(tǒng)一的應(yīng)用開發(fā)模型和核心 API,因此,盡管不同的存儲引擎擁有不同的特性,不過對于開發(fā)人員,應(yīng)用操作都是完全透明的。應(yīng)用層的連接并不直接訪問存儲引擎層,而是訪問 Mysql 提供的 Api,也就是說不管所操作的表對象使用什么存儲引擎,讀寫數(shù)據(jù)時執(zhí)...

    lidashuang 評論0 收藏0

發(fā)表評論

0條評論

IT那活兒

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<