B-樹和B+樹最重要的一個區別就是B+樹只有葉節點存放資料,其餘節點用來索引,而B-樹是每個索引節點都會有Data域。
B+樹
B+樹是為磁碟及其他儲存輔助裝置而設計一種平衡查詢樹(不是二叉樹)。B+樹中,所有記錄的節點按大小順序存放在同一層的葉節點中,各葉節點用指標進行連線。
資料庫中B+樹索引分為聚集索引(clustered index)和非聚集索引(secondary index).這兩種索引的共同點是內部都是B+樹,高度都是平衡的,葉節點存放著所有資料。不同點是葉節點是否存放著一整行資料。
B+樹有如下特點:
- B+樹每個節點可以包含更多的節點,這樣做有兩個原因,一個是降低樹的高度。另外一個是將資料範圍變為多個區間,區間越多,資料檢索越快。
- 每個節點不再只是儲存一個key了,可以儲存多個key。
- 非葉子節點儲存key,葉子節點儲存key和資料。
- 葉子節點兩兩指標相互連結,順序查詢效能更高。
通俗的講
- B+樹的非葉子節點只是儲存key,佔用空間非常小,因此每一層的節點能索引到的資料範圍更加的廣。換句話說,每次IO操作可以搜尋更多的資料。
- 葉子節點兩兩相連,符合磁碟的預讀特性。比如葉子節點儲存50和55,它有個指標指向了60和62這個葉子節點,那麼當我們從磁碟讀取50和55對應的資料的時候,由於磁碟的預讀特性,會順便把60和62對應的資料讀取出來。這個時候屬於順序讀取,而不是磁碟尋道了,加快了速度。
- 支援範圍查詢,而且部分範圍查詢非常高效,每個節點能索引的範圍更大更精確,也意味著 B+樹單次磁碟IO的資訊量大於B-樹,I/O效率更高。
原因是資料都是儲存在葉子節點這一層,並且有指標指向其他葉子節點,這樣範圍查詢只需要遍歷葉子節點這一層,無需整棵樹遍歷。
區域性性原理與磁碟預讀
由於磁碟的存取速度與記憶體之間鴻溝,為了提高效率,要儘量減少磁碟I/O.磁碟往往不是嚴格按需讀取,而是每次都會預讀,磁碟讀取完需要的資料,會順序向後讀一定長度的資料放入記憶體。而這樣做的理論依據是電腦科學中著名的區域性性原理:
當一個資料被用到時,其附近的資料也通常會馬上被使用,程式執行期間所需要的資料通常比較集中
B-樹
B-樹,這裡的 B 表示 balance( 平衡的意思),B-樹是一種多路自平衡的搜尋樹 它類似普通的平衡二叉樹,不同的一點是B-樹允許每個節點有更多的子節點。
B-樹有如下特點
- 所有鍵值分佈在整顆樹中。
- 任何一個關鍵字出現且只出現在一個結點中。
- 搜尋有可能在非葉子結點結束。
- 在關鍵字全集內做一次查詢,效能逼近二分查詢。
B-樹和B+樹的區別
- B+樹內節點不儲存資料,所有資料儲存在葉節點導致查詢時間複雜度固定為 log n。
- B-樹查詢時間複雜度不固定,與 key 在樹中的位置有關,最好為O(1)。
- B+樹葉節點兩兩相連可大大增加區間訪問性,可使用在範圍查詢等。
- B-樹每個節點 key 和 data 在一起,則無法區間查詢。
- B+樹更適合外部儲存(儲存磁碟資料)。由於內節點無 data 域,每個節點能索引的範圍更大更精確。
MongoDB 為什麼使用B-樹?
B+樹內節點不儲存資料,所有 data 儲存在葉節點導致查詢時間複雜度固定為 log n。而B-樹查詢時間複雜度不固定,與 key 在樹中的位置有關,最好為O(1)
我們說過,儘可能少的磁碟 IO 是提高效能的有效手段。MongoDB 是聚合型資料庫,而 B-樹恰好 key 和 data 域聚合在一起。
至於MongoDB為什麼使用B-樹而不是B+樹,可以從它的設計角度來考慮,它並不是傳統的關係性資料庫,而是以Json格式作為儲存的nosql,目的就是高效能,高可用,易擴充套件。首先它擺脫了關係模型,上面所述的優點2需求就沒那麼強烈了,其次Mysql由於使用B+樹,資料都在葉節點上,每次查詢都需要訪問到葉節點,而MongoDB使用B-樹,所有節點都有Data域,只要找到指定索引就可以進行訪問,無疑單次查詢平均快於Mysql。
雜湊索引
簡單地說,雜湊索引就是採用一定的雜湊演算法,把鍵值換算成新的雜湊值,檢索時不需要類似B+樹那樣從根節點到葉子節點逐級查詢,只需一次雜湊演算法即可立刻定位到相應的位置,速度非常快。
B+樹索引和雜湊索引的區別
- 如果是等值查詢,那麼雜湊索引明顯有絕對優勢,因為只需要經過一次演算法即可找到相應的鍵值;當然了,這個前提是,鍵值都是唯一的。如果鍵值不是唯一的,就需要先找到該鍵所在位置,然後再根據連結串列往後掃描,直到找到相應的資料。
- 如果是範圍查詢檢索,這時候雜湊索引就毫無用武之地了,因為原先是有序的鍵值,經過雜湊演算法後,有可能變成不連續的了,就沒辦法再利用索引完成範圍查詢檢索。
- 同理,雜湊索引也沒辦法利用索引完成排序,以及like ‘xxx%’ 這樣的部分模糊查詢(這種部分模糊查詢,其實本質上也是範圍查詢)。
- 雜湊索引也不支援多列聯合索引的最左匹配規則。
- B+樹索引的關鍵字檢索效率比較平均,不像B樹那樣波動幅度大,在有大量重複鍵值情況下,雜湊索引的效率也是極低的,因為存在所謂的雜湊碰撞問題。
- 解決Hash碰撞衝突方法總結 blog.csdn.net/zeb_perfect…
備註:以上內容均摘抄自網路,並非原創,僅供個人學習交流使用,望各路大牛,發現不對的地方,不吝賜教,留言即可。
參考
- https://blog.csdn.net/wwh578867817/article/details/50493940
- https://segmentfault.com/a/1190000004690721
- http://www.cnblogs.com/heiming/p/5865101.html
推薦閱讀
- Redis持久化RDB和AOF優缺點是什麼,怎麼實現的?我應該用哪一個?
- 為Java程式設計師金三銀四精心挑選的300餘道Java面試題與答案
- MySql常用30種SQL查詢語句優化方法
- 想進大廠?20道資料庫面試題你會多少?
- 想進大廠?50個多執行緒面試題,你會多少?(一)
- 想進大廠?50個多執行緒面試題,你會多少?(二)
- BTA 常問的 Java基礎40道常見面試題及詳細答案
- Spring 常見的一些面試題整理
- 常用的分散式事務解決方案介紹有多少種?
- 什麼是微服務架構?
- Dapper,大規模分散式系統的跟蹤系統
關注微信公眾號福利
關注微信公眾號「搜雲庫」獲取最新文章
【福利】公眾號後臺回覆 “進群”
【福利】邀請您進微信 “技術分享群”
【福利】群裡有很多技術大佬,免費提問,互相學習