【Java面試】Mysql為什麼使用B+Tree作為索引結構

跟著Mic學架構 發表於 2022-06-21
Java 面試 MySQL

一個工作8年的粉絲私信了我一個問題。

他說這個問題是去阿里面試的時候被問到的,自己查了很多資料也沒搞明白,希望我幫他解答。

問題是: “Mysql為什麼使用B+Tree作為索引結構”

關於這個問題,看看普通人和高手的回答。

普通人:

B+數它的特徵就是相對B數來說他的這個非葉子節點不存資料,所有的資料都存在葉子節點

相對於B數來說他的查詢次數IO次數會更穩。

高手:

關於這個問題 ,我從幾個方面來回答。

首先,常規的資料庫儲存引擎,一般都是採用B樹或者B+樹來實現索引的儲存。

因為B樹是一種多路平衡樹,用這種儲存結構來儲存大量資料,它的整個高度會相比二叉樹來說,會矮很多。

而對於資料庫來說,所有的資料必然都是儲存在磁碟上的,而磁碟IO的效率實際上是很低的,特別是在隨機磁碟IO的情況下效率更低。

所以樹的高度能夠決定磁碟IO的次數,磁碟IO次數越少,對於效能的提升就越大,這也是為什麼採用B樹作為索引儲存結構的原因。

image-20220422124736684

但是在Mysql的InnoDB儲存引擎裡面,它用了一種增強的B樹結構,也就是B+樹來作為索引和資料的儲存結構。

相比較於B樹結構,B+樹做了幾個方面的優化。

  1. B+樹的所有資料都儲存在葉子節點,非葉子節點只儲存索引。
  2. 葉子節點中的資料使用雙向連結串列的方式進行關聯。

image-20220422125222216

使用B+樹來實現索引的原因,我認為有幾個方面。

  1. B+樹非葉子節點不儲存資料,所以每一層能夠儲存的索引數量會增加,意味著B+樹在層高相同的情況下儲存的資料量要比B樹要多,使得磁碟IO次數更少。
  2. 在Mysql裡面,範圍查詢是一個比較常用的操作,而B+樹的所有儲存在葉子節點的資料使用了雙向連結串列來關聯,所以在查詢的時候只需查兩個節點進行遍歷就行,而B樹需要獲取所有節點,所以B+樹在範圍查詢上效率更高。
  3. 在資料檢索方面,由於所有的資料都儲存在葉子節點,所以B+樹的IO次數會更加穩定一些。
  4. 因為葉子節點儲存所有資料,所以B+樹的全域性掃描能力更強一些,因為它只需要掃描葉子節點。但是B樹需要遍歷整個樹。

另外,基於B+樹這樣一種結構,如果採用自增的整型資料作為主鍵,還能更好的避免增加資料的時候,帶來葉子節點分裂導致的大量運算的問題。

總的來說,我認為技術方案的選型,更多的是去解決當前場景下的特定問題,並不一定是說B+樹就是最好的選擇,就像MongoDB裡面採用B樹結構,本質上來說,其實是關係型資料庫和非關係型資料庫的差異。

以上就是我對這個問題的理解。

總結

對於“為什麼要選擇xx技術”的問題,其實很好回答。

只要你對這個技術本身的特性足夠了解,那麼自然就知道為什麼要這麼設計。

就像,我們在業務開發中,知道什麼時候使用List,什麼時候使用Map,道理是一樣的。

如果有任何面試問題、職業發展問題、學習問題,都可以私信我。

file

版權宣告:本部落格所有文章除特別宣告外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 Mic帶你學架構
如果本篇文章對您有幫助,還請幫忙點個關注和贊,您的堅持是我不斷創作的動力。歡迎關注同名微信公眾號獲取更多技術乾貨!