平衡二叉樹是基於分治思想採用二分法的策略提升數據查找速度的二叉樹結構。非葉子結點最多隻能有兩個子結點,且左邊子結點點小於當前結點值,右邊子結點大於當前結點樹,而且爲保證查詢性能增增刪結點時要保證左右兩邊結點層級相差不大於1,具體實現有AVL、Treap、紅黑樹等。Java中TreeMap就是基於紅黑樹實現的。sql
B樹與平衡二叉樹區別是它是平衡多路查找樹,它每一個節點包含的關鍵字增多了,在應用時可利用磁盤塊的原理把結點大小限制在磁盤大小範圍內從而優化讀寫速度,同時樹的關鍵字增多後層級比原理的二叉樹少許,減小了數據查找次數和複雜度。數據庫
B+樹是B樹基礎上爲了更充分的利用結點空間,讓遍歷查詢速度更穩定而擴展的結構,它規定只在葉子節點存數據,非葉子結點只存索引,且葉子結點用一個鏈表鏈接起來。緩存
(1)B+跟B樹不一樣B+樹的非葉子節點不保存關鍵字記錄的指針,這樣使得B+樹每一個節點所能保存的關鍵字大大增長;數據結構
(2)B+樹葉子節點保存了父節點的全部關鍵字和關鍵字記錄的指針,每一個葉子節點的關鍵字從小到大連接;性能
(3)B+樹的根節點關鍵字數量和其子節點個數相等;優化
(4)B+的非葉子節點只進行數據索引,不會存實際的關鍵字記錄的指針,全部數據地址必需要到葉子節點才能獲取到,因此每次數據查詢的次數都同樣;操作系統
在B樹的基礎上每一個節點存儲的關鍵字數更多,樹的層級更少因此查詢數據更快,全部指關鍵字指針都存在葉子節點,因此每次查找的次數都相同因此查詢速度更穩定;.net
B*樹是在B+基礎上給非根非葉子結點增長指向兄弟結點的指針,所以能夠向兄弟結點轉移關鍵字使其分解次數變得更少。3d
https://zhuanlan.zhihu.com/p/27700617指針
LSM樹是內存中完成增、刪、改操做從而寫性能更高,使用索引修改比讀更頻繁的場景。
https://blog.csdn.net/u010853261/article/details/78217823
爲何說B+tree比B樹更適合實際應用中操做系統的文件索引和數據庫索引?
(1) B+tree的磁盤讀寫代價更低
B+tree的內部結點並無指向關鍵字具體信息的指針。所以其內部結點相對B樹更小。若是把全部同一內部結點的關鍵字存放在同一盤塊中,那麼盤塊所能容納的關鍵字數量也越多。一次性讀入內存中的須要查找的關鍵字也就越多。相對來講IO讀寫次數也就下降了。舉個例子,假設磁盤中的一個盤塊容納16bytes,而一個關鍵字2bytes,一個關鍵字具體信息指針2bytes。一棵9階B-tree(一個結點最多8個關鍵字)的內部結點須要2個盤快。而B+ 樹內部結點只須要1個盤快。當須要把內部結點讀入內存中的時候,B 樹就比B+ 樹多一次盤塊查找時間(在磁盤中就是盤片旋轉的時間)。
(2)B+tree的查詢效率更加穩定
因爲非葉子結點並非最終指向文件內容的結點,而只是葉子結點中關鍵字的索引。因此任何關鍵字的查找必須走一條從根結點到葉子結點的路。全部關鍵字查詢的路徑長度相同,致使每個數據的查詢效率至關。(3)B樹在提升了磁盤IO性能的同時並無解決元素遍歷的效率低下的問題。正是爲了解決這個問題,B+樹應運而生。B+樹只要遍歷葉子節點就能夠實現整棵樹的遍歷。並且在數據庫中基於範圍的查詢是很是頻繁的,而B樹不支持這樣的操做(或者說效率過低)。
LSM樹
目前常見的主要的三種存儲引擎是:哈希、B+樹、LSM樹:
- 哈希存儲引擎:是哈希表的持久化實現,支持增、刪、改以及隨機讀取操做,但不支持順序掃描,對應的存儲系統爲key-value存儲系統。對於key-value的插入以及查詢,哈希表的複雜度都是O(1),明顯比樹的操做O(n)快,若是不須要有序的遍歷數據,哈希表性能最好。
- B+樹存儲引擎是B+樹的持久化實現,不只支持單條記錄的增、刪、讀、改操做,還支持順序掃描(B+樹的葉子節點之間的指針),對應的存儲系統就是關係數據庫(Mysql等)。
- LSM樹(Log-Structured MergeTree)存儲引擎和B+樹存儲引擎同樣,一樣支持增、刪、讀、改、順序掃描操做。並且經過批量存儲技術規避磁盤隨機寫入問題。固然凡事有利有弊,LSM樹和B+樹相比,LSM樹犧牲了部分讀性能,用來大幅提升寫性能。
上面三種引擎中,LSM樹存儲引擎的表明數據庫就是HBase.
LSM樹核心思想的核心就是放棄部分讀能力,換取寫入的最大化能力。LSM Tree ,這個概念就是結構化合並樹的意思,它的核心思路其實很是簡單,就是假定內存足夠大,所以不須要每次有數據更新就必須將數據寫入到磁盤中,而能夠先將最新的數據駐留在內存中,等到積累到足夠多以後,再使用歸併排序的方式將內存內的數據合併追加到磁盤隊尾(由於全部待排序的樹都是有序的,能夠經過合併排序的方式快速合併到一塊兒)。
日誌結構的合併樹(LSM-tree)是一種基於硬盤的數據結構,與B+tree相比,能顯著地減小硬盤磁盤臂的開銷,並能在較長的時間提供對文件的高速插入(刪除)。然而LSM-tree在某些狀況下,特別是在查詢須要快速響應時性能不佳。一般LSM-tree適用於索引插入比檢索更頻繁的應用系統。
LSM樹和B+樹的差別主要在於讀性能和寫性能進行權衡。在犧牲的同時尋找其他補救方案:
(a)LSM具備批量特性,存儲延遲。當寫讀比例很大的時候(寫比讀多),LSM樹相比於B樹有更好的性能。由於隨着insert操做,爲了維護B+樹結構,節點分裂。讀磁盤的隨機讀寫機率會變大,性能會逐漸減弱。
(b)B樹的寫入過程:對B樹的寫入過程是一次原位寫入的過程,主要分爲兩個部分,首先是查找到對應的塊的位置,而後將新數據寫入到剛纔查找到的數據塊中,而後再查找到塊所對應的磁盤物理位置,將數據寫入去。固然,在內存比較充足的時候,由於B樹的一部分能夠被緩存在內存中,因此查找塊的過程有必定機率能夠在內存內完成,不過爲了表述清晰,咱們就假定內存很小,只夠存一個B樹塊大小的數據吧。能夠看到,在上面的模式中,須要兩次隨機尋道(一次查找,一次原位寫),纔可以完成一次數據的寫入,代價仍是很高的。
(c)LSM優化方式:
- Bloom filter: 就是個帶隨機機率的bitmap,能夠快速的告訴你,某一個小的有序結構裏有沒有指定的那個數據的。因而就能夠不用二分查找,而只需簡單的計算幾回就能知道數據是否在某個小集合裏啦。效率獲得了提高,但付出的是空間代價。
- compact:小樹合併爲大樹:由於小樹性能有問題,因此要有個進程不斷地將小樹合併到大樹上,這樣大部分的老數據查詢也能夠直接使用log2N的方式找到,不須要再進行(N/m)*log2n的查詢了