Java高级工程师每日面试题精选,面试经历分享
MySQL為何不選擇平衡二叉樹
既然平衡二叉樹解決了普通二叉樹的問題,那么mysql為何不選擇平衡二叉樹作為索引呢?
索引需要存儲什么
讓我們想一想,如果我們要把索引存起來,那么應(yīng)該存哪些信息呢,它應(yīng)該存儲三塊信息:
-
索引的值:就是表里面索引列對應(yīng)的值。
-
數(shù)據(jù)的磁盤地址(通過磁盤地址找到當(dāng)前數(shù)據(jù))或者直接存儲整條數(shù)據(jù)。
-
子節(jié)點的引用:我們需要從根節(jié)點往下走,所以需要知道左右子節(jié)點的地址。 根據(jù)這三點,可以有如下大致的一個簡單的結(jié)構(gòu)圖:
上圖中數(shù)字表示的是索引的值,0x開頭的表示磁盤地址,根節(jié)點中存了左右節(jié)點的引用。
AVL樹用來存儲索引存在什么問題
我們知道,頁(Page)是 Innodb 存儲引擎用于管理數(shù)據(jù)的最小磁盤單位,頁的默認(rèn)大小為16KB。頁也就是上圖中的節(jié)點,每查詢一次節(jié)點就需要進(jìn)行一次IO操作,IO操作是一種非常耗時的操作,很多業(yè)務(wù)系統(tǒng)的瓶頸都是卡在IO操作上,所以如果我們需要提高查詢效率的辦法之一就是減少IO次數(shù),那么問題就來了,AVL樹一個節(jié)點上只存了一個關(guān)鍵字(索引值)+一個磁盤地址+左右節(jié)點的引用,這是遠(yuǎn)遠(yuǎn)達(dá)不到16KB的,會浪費了大量的空間。
上圖中如果我們要找到6這條數(shù)據(jù),需要進(jìn)行3次IO(獲取一個節(jié)點就是一個IO操作),如果這棵樹很高的話,就會進(jìn)行大量的IO操作,所以說AVL樹存在的最大問題就是空間利用不足,浪費了大量空間,數(shù)據(jù)量大的時候就會成為一顆瘦高的樹,那么我們可以怎么改進(jìn)呢?答案很明顯了,那就是每個磁盤塊多存一點東西,也就是說每個磁盤多存幾個關(guān)鍵字,因為關(guān)鍵字越多,路數(shù)越多;路數(shù)越多,樹也就越矮越胖,相應(yīng)的操作IO次數(shù)就會越少。
多路平衡樹(Balanced Tree)
多路平衡樹簡稱B樹,又稱B-樹,和AVL樹一樣,B樹在枝節(jié)點和葉子節(jié)點存儲鍵值、磁盤地址、左右節(jié)點引用。請看下圖的一個多路平衡樹的示例:
B樹的特點
相比較AVL樹,B樹一個磁盤上可以存多個關(guān)鍵字(值),而且有一個特點就是:
- 分叉數(shù)(路數(shù))永遠(yuǎn)比關(guān)鍵字?jǐn)?shù)多1。 我們可以畫出如下簡圖(下圖中只畫了3路,即兩個關(guān)鍵字,實際取決于一頁能存儲多少個關(guān)鍵字):
從上圖可以很明顯的看出,同樣高度的樹,B樹能存的數(shù)據(jù)遠(yuǎn)遠(yuǎn)大于平衡二叉樹。
B樹是如何查找數(shù)據(jù)的
以上圖為例,假如我們要找key=32這個數(shù)字,首先獲取到根節(jié)點,發(fā)現(xiàn)18小于key,所以往右邊走,獲取到右邊的數(shù)據(jù),54和76,這時候遵循以下原則:
-
key<54,命中最左邊分叉;
-
key=54,直接命中,返回數(shù)據(jù);
-
54<key<76,走中間的一個分叉;
-
key=76,直接命中,返回數(shù)據(jù);
-
key>76,命中右邊分支; 這里因為key=32,所以走得是第1條,命中左邊分支,這時候再去獲取左邊分支,獲取到32和50,比較發(fā)現(xiàn)key=32,命中,返回數(shù)據(jù)。
從上面我們可以看出B樹效率相對于AVL樹,在數(shù)據(jù)量大的情況效率已經(jīng)提高了很多,那么為什么MySQL還是不選擇B樹作為索引呢? 那么接下來讓我們先看看改良版的B+樹,然后再下結(jié)論吧!
B+樹
B+樹由B樹改良而來,屬于改良版的多路平衡查找樹。 首先讓我們來看看B+樹到底長什么樣呢:
對比B+樹,我們可以發(fā)現(xiàn)一個很明顯的區(qū)別就是葉子節(jié)點有一個箭頭指引而且從左到右是有序的。
InnoDB中使用的B+樹相比較于傳統(tǒng)B+樹,改進(jìn)之后的B+樹具有以下特點
InnoDB中B+樹的特點
-
它的關(guān)鍵字的數(shù)量是跟路數(shù)相等的。
-
B+樹的根節(jié)點和枝節(jié)點中都不會存儲數(shù)據(jù),只有葉子節(jié)點才存儲數(shù)據(jù)。而搜索到關(guān)鍵字不會直接返回,會到最后一層的葉子節(jié)點。
-
B+樹的每個葉子節(jié)點增加了一個指向相鄰葉子節(jié)點的指針,它的最后一個數(shù)據(jù)會指向下一個葉子節(jié)點的第一個數(shù)據(jù),形成了一個有序鏈表的結(jié)構(gòu)。
-
它是根據(jù)左閉右開的區(qū)間來檢索數(shù)據(jù)的 按照B+樹的特點,我們可以畫出一個存儲數(shù)據(jù)的簡圖,如下:
最后
給大家送上一份福利,領(lǐng)取方式:戳這里免費下載
Java架構(gòu)進(jìn)階面試及知識點文檔筆記
這份文檔共498頁,其中包括Java集合,并發(fā)編程,JVM,Dubbo,Redis,Spring全家桶,MySQL,Kafka等面試解析及知識點整理
Java分布式高級面試問題解析文檔
其中都是包括分布式的面試問題解析,內(nèi)容有分布式消息隊列,Redis緩存,分庫分表,微服務(wù)架構(gòu),分布式高可用,讀寫分離等等!
互聯(lián)網(wǎng)Java程序員面試必備問題解析及文檔學(xué)習(xí)筆記
Java架構(gòu)進(jìn)階視頻解析合集
)]
互聯(lián)網(wǎng)Java程序員面試必備問題解析及文檔學(xué)習(xí)筆記
[外鏈圖片轉(zhuǎn)存中…(img-kDFntc1E-1625205424045)]
Java架構(gòu)進(jìn)階視頻解析合集
總結(jié)
以上是生活随笔為你收集整理的Java高级工程师每日面试题精选,面试经历分享的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java高级工程师必看系列,已拿到off
- 下一篇: 极米play怎么连蓝牙键盘?