B-Tree

B-Tree

 


假如每個盤塊可以正好存放一個B樹的結點(正好存放2個文件名)。那麼一個BTNODE結點就代表一個盤塊,而子樹指針就是存放另外一個盤塊的地址。

下面,咱們來模擬下查找文件29的過程:

1 根據根結點指針找到文件目錄的根磁盤塊1,將其中的信息導入內存。【磁盤IO操作 1次】    

2 此時內存中有兩個文件名17、35和三個存儲其他磁盤頁面地址的數據。根據算法我們發現:17<29<35,因此我們找到指針p2。

根據p2指針,我們定位到磁盤塊3,並將其中的信息導入內存。【磁盤IO操作 2次】    

1 此時內存中有兩個文件名26,30和三個存儲其他磁盤頁面地址的數據。根據算法我們發現:26<29<30,因此我們找到指針p2。

根據p2指針,我們定位到磁盤塊8,並將其中的信息導入內存。【磁盤IO操作 3次】    

1 此時內存中有兩個文件名28,29。根據算法我們查找到文件名29,並定位了該文件內存的磁盤地址。

分析上面的過程,發現需要3次磁盤IO操作和3次內存查找操作。關於內存中的文件名查找,由於是一個有序表結構,可以利用折半查找提高效率。至於IO操作是影響整個B樹查找效率的決定因素。

當然,如果我們使用平衡二叉樹的磁盤存儲結構來進行查找,磁盤4次,最多5次,而且文件越多,B樹比平衡二叉樹所用的磁盤IO操作次數將越少,效率也越高

 

B+-Tree

 

 

B+-Tree是應文件系統所需而產生的一種B-Tree的變形樹。一棵m階的B+樹和m階的B-Tree異同點在於:

3 有n棵子樹的節點中含有n-1個關鍵字

4 所有的葉子節點中包含了全部關鍵字的信息,及指向含有這些關鍵字記錄的指針,且葉子結點本身依關鍵字的大小自小而大的順序連接。(而B樹的葉子節點並沒有包括全部需要查找的信息)

5 所有的非終端結點可以看成是索引部分,節點中僅含有其子樹根結點中最大(或最小)關鍵字。(而B樹的非終端結點也包含需要查找的有效信息)

a)     爲什麼說B+-treeB 樹更適合實際應用中操作系統的文件索引和數據庫索引?

6 B+Tree的磁盤讀寫代價更低

       B+Tree的內部結點並沒有指向關鍵字具體信息的指針。因此其內部結點相對B樹更小。如果把所有同一內部結點的關鍵字存在同一盤塊中,那麼盤塊所能容納的關鍵字數量也越多。一次性讀入內存中的需要查找的關鍵字也就越多。相對來說IO讀寫次數也就降低了。

       舉個例子,假設磁盤中的一個盤塊容納16bytes,而一個關鍵字2bytes,一個關鍵字具體信息指針2bytes。一棵9階B-tree(一個結點最多8個關鍵字)的內部結點需要2個盤快。而B樹內部結點只需要1個盤快。當需要把內部結點讀入內存中的時候,B 樹就比B樹多一次盤塊查找時間(在磁盤中就是盤片旋轉的時間)。

1 B+Tree的查詢效率更加穩定

       由於非終端結點並不是最終指向文件內容的結點,而只是葉子結點中關鍵字的索引。所以任何關鍵字的查找必須走一條從根結點到葉子結點的路。所有關鍵字查詢的路徑長度相同,導致每一個數據的查詢效率相當。

 

MySql的索引實踐:

 

MyISAM索引實現

       MyISAM引擎使用B+Tree作爲索引結構,葉結點的data域存放的是數據記錄的地址。下圖是MyISAM索引的原理圖:

 

這裏設表一共有三列,假設我們以Col1爲主鍵,則上圖是一個MyISAM表的主索引示意,可以看出MyISAM的索引文件僅僅保存數據記錄的地址。在MyISAM中,主所以和輔助索引在結構上沒有任何區別,只是主索引要求key是唯一的,而輔助索引的key可以重複。如果我們在Col2上建立一個輔助索引,則此索引的結構如下圖所示:

 

同樣也是一棵B+Tree,data域保存數據記錄的地址。因此,MyISAM中索引檢索的算法爲首先按照B+Tree搜索算法搜索索引,如果指定的key存在,則取出其data域的值爲地址,讀取相應數據記錄。

MyISAM的索引方式也叫做“非聚集”的,之所以這麼稱呼是爲了域InnoDB的聚集區分。

 

InnoDB索引實現:

      雖然InnoDB也是使用B+Tree作爲索引結構,但是具體實現方式卻與MyISAM截然不同。

       第一個重大區別就是InnoDB的數據文件本身就是索引文件。從上文知道,MyISAM索引文件和數據文件是分離的,索引文件僅保存數據記錄的地址。而在InnoDB中,表數據文件本身就是按B+Tree組織的一個索引結構,這棵樹的葉子結點data域保存了完整的數據記錄。這個索引的key是數據表的主鍵,因此InnoDB表數據文件本身就是主索引。

 

圖10是InnoDB主索引(同時也是數據文件)的示意圖,可以看到葉結點包含了完整的數據記錄。這種索引叫做聚集索引。因爲InnoDB的數據文件本身要按主鍵聚集,所以InnoDB要求表必須有主鍵(MyISAM可以沒有),如果沒有顯示指定,則MySQL系統會自動選擇一個可以唯一標識數據記錄的列作爲主鍵,如果不存在這種列,則MySQL會自動爲InnoDB表生成一個隱含字段作爲主鍵,這個字段長度爲6個字節,類型爲長整形。

        第二個MyISAM索引的不同時InnoDB的輔助索引data域存儲相應記錄主鍵的值而不是地址。換句話說,InnoDB的所有輔助索引都引用主鍵的data域。列入,在Col3上的一個輔助索引:

聚集索引這種實現方式使得按主鍵的搜索十分高效,但是輔助索引需要搜索兩遍索引:首先檢索輔助索引獲得主鍵,然後用主鍵到主索引中檢索獲得記錄。

       瞭解不同存儲引擎的所以實現方式對於正確使用和優化索引都非常有幫助,例如知道了InnoDB的索引實現後,就很容易明白爲什麼不建議使用過長的字段作爲主鍵,因爲所有輔助索引都引用主索引,過長的主索引會令輔助索引變的過大。再例如,用非單調的字段作爲主鍵在InnoDB中不是個好主意,因爲InnoDB數據文件本身是一棵B+Tree。非單調的主鍵會造成在插入新記錄時數據文件爲了維持B+Tree的特性而頻繁的分裂調整,十分低效,而使用自增字段作爲主鍵則是一個很好的選擇。

 

 

 推薦:

http://blog.csdn.net/v_JULY_v/article/details/6530142

 

http://blog.csdn.net/chenhuajie123/article/details/11951327

 

http://blog.csdn.net/wangpingfang/article/details/7426943

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章