Mysql InnoDB B+樹索引和哈希索引的區別? MongoDB 爲何使用B-樹?

B-樹和B+樹最重要的一個區別就是B+樹只有葉節點存放數據,其他節點用來索引,而B-樹是每一個索引節點都會有Data域。html

B+樹

B+樹是爲磁盤及其餘存儲輔助設備而設計一種平衡查找樹(不是二叉樹)。B+樹中,全部記錄的節點按大小順序存放在同一層的葉節點中,各葉節點用指針進行鏈接。程序員

數據庫中B+樹索引分爲彙集索引(clustered index)和非彙集索引(secondary index).這兩種索引的共同點是內部都是B+樹,高度都是平衡的,葉節點存放着全部數據。不一樣點是葉節點是否存放着一整行數據。面試

B+樹有以下特色:算法

  • B+樹每一個節點能夠包含更多的節點,這樣作有兩個緣由,一個是下降樹的高度。另一個是將數據範圍變爲多個區間,區間越多,數據檢索越快。
  • 每一個節點再也不只是存儲一個key了,能夠存儲多個key。
  • 非葉子節點存儲key,葉子節點存儲key和數據。
  • 葉子節點兩兩指針相互連接,順序查詢性能更高。

通俗的講sql

  • B+樹的非葉子節點只是存儲key,佔用空間很是小,所以每一層的節點能索引到的數據範圍更加的廣。換句話說,每次IO操做能夠搜索更多的數據。
  • 葉子節點兩兩相連,符合磁盤的預讀特性。好比葉子節點存儲50和55,它有個指針指向了60和62這個葉子節點,那麼當咱們從磁盤讀取50和55對應的數據的時候,因爲磁盤的預讀特性,會順便把60和62對應的數據讀取出來。這個時候屬於順序讀取,而不是磁盤尋道了,加快了速度。
  • 支持範圍查詢,並且部分範圍查詢很是高效,每一個節點能索引的範圍更大更精確,也意味着 B+樹單次磁盤IO的信息量大於B-樹,I/O效率更高。

緣由是數據都是存儲在葉子節點這一層,而且有指針指向其餘葉子節點,這樣範圍查詢只須要遍歷葉子節點這一層,無需整棵樹遍歷。數據庫

局部性原理與磁盤預讀

因爲磁盤的存取速度與內存之間鴻溝,爲了提升效率,要儘可能減小磁盤I/O.磁盤每每不是嚴格按需讀取,而是每次都會預讀,磁盤讀取完須要的數據,會順序向後讀必定長度的數據放入內存。而這樣作的理論依據是計算機科學中著名的局部性原理:segmentfault

當一個數據被用到時,其附近的數據也一般會立刻被使用,程序運行期間所須要的數據一般比較集中微信

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碰撞衝突方法總結 https://blog.csdn.net/zeb_perfect/article/details/52574915

備註:以上內容均摘抄自網絡,並不是原創,僅供我的學習交流使用,望各路大牛,發現不對的地方,不吝賜教,留言便可

參考

推薦閱讀

關注微信公衆號福利

關注微信公衆號「搜雲庫」獲取最新文章

福利】公衆號後臺回覆 「進羣
福利】邀請您進微信 「技術分享羣
福利】羣裏有不少技術大佬,免費提問,互相學習
關注公衆號-搜雲庫

相關文章
相關標籤/搜索