B樹與B+樹與磁盤讀取的聯繫

首先,講一下什麼是索引

索引就好比是書的目錄,比如當我們查看一本字典的時候,目錄就相當於我們的對照表
也就是說,目錄裏的內容來源於書本但卻獨立於書本,但是呢,目錄又是這本書裏的一頁(●ˇ∀ˇ●),就醬

然後,講一下訪存的問題

我們都知道,計算機的存儲管理是分層的,各層次之間的速度差距比較大,尤其是輔存(磁盤)和主存之間的速度
那麼,我們都知道磁盤訪問比較慢,爲啥會這麼慢呢?
首先,cpu訪問磁盤時,磁盤主要乾了這些事

  1. 尋道:磁頭擺一擺,找到對應的柱面
  2. 定位:盤面轉一轉,磁頭定位到指定扇區

在這兩個步驟中,因爲是機械操作,我們都曉得,這機械運動哪能比得上人家主存的電信號傳播呢( ̄_, ̄ ),所以自然就慢了不少,磁盤訪問慢了,訪問效率自然就跟不上了
既然這麼慢,那我們肯定就得想辦法,能不能在不改變這種機械運動的情況下提升一下這個訪存效率呢?
這就好比你查字典,給你一個字,你翻一翻,給你一堆字,你翻n翻,查半年?
能不能有個好一點的目錄,一搜搜一篇,命中率嘎嘎的那種?

所以,這就要求我們建立一個好的索引也就是所謂的好目錄來幫助我們啦

磁盤讀寫原理

這裏主要介紹一下磁盤預讀原理,在這之前,要講一下預讀原理的基礎,程序的局部性原理
程序的局部性原理是指程序在執行時呈現出局部性規律,即在一段時間內,整個程序的執行僅限於程序中的某一部分。相應地,執行所訪問的存儲空間也侷限於某個內存區域(也就是說,這個程序在這一小段時間內只會用這一部分內存的這一小撮數據)
磁盤預讀: 有了這個局部性原理,那我就想了,這程序執行依次要一個數據,現在我知道它要的數據基本都是一堆一堆的湊在一起的,那我就可以在它要之前我這個磁盤先讀着我這個扇區下面的內容,反正我這磁盤轉着挺快的,順序讀取效率蠻高,我先讀着,你要不要另說(●ˇ∀ˇ●)
通過預讀呢,我們就可以提前準備好要用數據,提升I/O效率

那麼我們怎麼去預讀呢,預讀多大呢?
預讀的長度一般爲頁(page)的整倍數。頁是計算機管理存儲器的邏輯塊,硬件及操作系統往往將主存和磁盤存儲區分割爲連續的大小相等的塊,每個存儲塊稱爲一頁(在許多操作系統中,頁得大小通常爲4k),主存和磁盤以頁爲單位交換數據。當程序要讀取的數據不在主存中時,會觸發一個缺頁異常,此時系統會向磁盤發出讀盤信號,磁盤會找到數據的起始位置並向後連續讀取一頁或幾頁載入內存中,然後異常返回,程序繼續運行。(抄抄抄(❤ ω ❤))

B樹和B+樹

具體結構不說了,大家既然看這篇文章想必是都懂
這兩種數據結構其實就是我們要構造的索引所用到的數據類型
在實際設計中,我們把一個結點設爲一個頁,爲什麼這麼幹呢,因爲磁盤預讀是以頁爲單位的,所以這樣的話一頁就代表訪問一次磁盤,也就是代表一次I/O操作
下面我們分別來看一下這兩種不同的索引

B樹: 我們假設如果是4階的,那麼每個結點最多3個關鍵字,最少兩個(根節點最少1個),也就是說,我們最多也就要訪問3次磁盤就可以完成訪存,而傳統的訪存需要每一個關鍵字都進行訪存,可以看出B樹的優勢
注意B樹的非葉結點不單單隻有key值,還有key對應數據在磁盤的具體地址

B+樹: 相對與B樹而言,B+樹的非葉結點值只存有key值,不含有衛星數據,比較而言就會有更大的空間,就可以存更多的key值,就會顯得更加“矮胖”,矮了操作數就相對會更少一些
同時由於B+樹增加了一個最小關鍵字的根結點,所以順序訪問更加便捷

參考資料:
https://blog.csdn.net/hguisu/article/details/7408047
https://blog.csdn.net/dazhong159/article/details/7964245
https://zhuanlan.zhihu.com/p/54102723

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