java磁盘读写b 树_原来你是这样的B+树
前言
B+樹是目前最常用的一種索引數據結構,通常用于數據庫和操作系統的文件系統中,本文就網上的知識點與個人理解結合分享,如有錯誤,歡迎探討及指正.
定義
B+樹是B樹的一種變形形式,B+樹上的葉子結點存儲關鍵字以及相應記錄的地址,葉子結點以上各層作為索引使用。一棵m階的B+樹定義如下(注意: B+樹的階數m表示一個節點最多能有m個子節點,也就是每個節點上最多的鍵值個數.):
1.每個結點至多有m個子女;
2.除根結點外,每個結點至少有[m/2]個子女,根結點至少有兩個子女;
3.有k個子女的結點必有k個關鍵字。
B+樹的查找與B樹不同,當索引部分某個結點的關鍵字與所查的關鍵字相等時,并不停止查找,應繼續沿著這個關鍵字左邊的指針向下,一直查到該關鍵字所在的葉子結點為止。
圖文理解
下面我們通過圖文詳解來深入理解B+樹
不同階數的B+樹對比
我們將數組[1,2,3,4…20]分別插入3階、4階、5階、6階B+數,最終存儲的數據結構如下圖:
3階B+樹 :
4階B+數:
5階B+數:
6階B+數:
通過上面對比,我們不難發現以下特征:
所有節點均有序排列;
樹節點總是樹高平衡;
m階的B+樹除了根節點之外的每個節點都包含最少 m/2個元素,但最多包含 m-1 個元素(文末提供在線測試地址,可以自行刪減元素,觀察葉子結點的變化);
對于任意的節點有最多 m 個子指針;
對于所有內部節點,子指針的數目總是比元素的數目多一個;
階數越大,數的高度越小.
所有數據存儲在葉子結點上,非葉子節點不存儲行數據,是為了能存儲更多索引鍵,從而降低B+樹的高度,進而減少IO次數.
B+樹insert/delete操作后數據結構的變化
本次我們演示4階B+樹操作的變化過程
第一步:我們先插入數字1、2、3
第二步:插入數字4,由于每個節點最多只能有m-1個元素,即超過3個后需要進行拆分頁,而目前只有一個根節點,所以旋轉后樹的深度+1.
第三步:分別插入數字5、6,根據結構的特性拆分頁,如下圖
第四步:分別插入數字7、8、9
插入10的時候,觸發每個節點最多只能有m-1個元素的特性,同時觸發了[任意的節點有最多 m 個子指針]的特性,所以繼續旋轉后樹的深度+1.
第五步:前面四步演示了樹的旋轉以及拆分頁,接下來我們看下刪除元素會是什么樣的效果,先刪除元素10看下:
在第四步最后我們增加一個元素10,觸發了B+樹的特性調整了樹的高度,現在我們刪除元素10,從上圖可以看出樹的高度沒有變化,這點跟平衡樹不一樣,我們繼續刪元素.
刪除元素7之后,層級沒有變化,但是第二級的右子節點元素值發生了旋轉,由7變成了6,繼續刪除元素6:
我們發現刪除元素6后,樹的層級發生了變化,這是因為觸發了[對于所有內部節點,子指針的數目總是比元素的數目多一個]這一特性,然后根據最優算法降低了樹的高度,同時我們發現,此時的5個元素排列并沒有恢復到我們之前從元素[1-5]插入后的結構,這點非常妙,不管接下來是新增、刪除、查找你會發現效率都是最優的.
B+樹的查找
我們還是以4階樹10個元素為例,查找元素6
從上可以看出查找路線與二叉樹的查找規則一致,繼續查找元素5
結合這兩次查找,可以看出都消耗了3次IO找到數據,這個次數剛好等于數的高度,數據量少時看不出這個效率,假設是100階的樹,存儲了400w+數據,實際也是3次IO就可以找到想要的數據,這個時候B+樹的優勢就體現出來了.
至此,相信你對B+樹又有了更直觀的認識,接下來我們再聊聊mysql應用的B+樹索引.
mysql的B+樹索引
mysql的B+樹索引有多少階?
對于這個問題,我們需要先了解下磁盤相關知識.
磁盤的最小存儲單位是扇區(512字節)
磁盤的讀取是以塊為基本單位,一塊大小為8個扇區,即4kb
B+樹的每一個節點占用的空間就是一個塊大小
由于B+樹節點中只存儲元素和指針.如果有n個元素,那么就有n+1個指針,假設現在索引存儲int類型的值,一個int(32位)占用4個字節,一個指針占用8個字節,那么一個塊最多能存4096/(4n+8(n+1))即340個元素,那么索引即為341階(m階數最多包含m-1個元素).
mysql的B+樹索引能存多少數據?
以innodb引擎的索引數據結構為例,它的存儲單元為一頁,每頁大小默認為16kb,該值可以通過參數調整,如下圖.
假設每個節點中索引元素占8個字節,指針占用6個字節,那么每頁可存(16*1024)/(8+6)=1170個索引元素
假設B+樹的高度為3,一條數據大小為1k,那么:
第一層可以存1170個元素;
第二層可以存11701170=1368900個元素;
第三層屬于葉子結點,可以存的數據條數為頁大小16k/每條數據大小1k,即16條,那么總共可以存儲的數據條數即為161368900=21902400
總結:mysql 單表使用innodb引擎(表數據文件本身就是一個B+樹組織的索結構文件),默認至少可以存2000w數據(實際每個節點不只存儲了元素及指針),并且查找數據,最多3次io即可.
資料參考
非常經典的數據結構可視化工具
https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html
百度百科
https://baike.baidu.com/item/B+%E6%A0%91/7845683#reference-[3]-1168762-wrap
歡迎關注個人訂閱號:Java技術寶典 ,及時獲取最新分享.
總結
以上是生活随笔為你收集整理的java磁盘读写b 树_原来你是这样的B+树的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 男子花12万买世界杯彩票没中要求退款,店
- 下一篇: java生成电子证书_关于Java:使用