爲什麼要用建立索引以及爲什麼要用b+樹?

前言:

https://www.youtube.com/watch?v=aZjYr87r1b8 看到了一個印度阿三講述的B樹和B +樹。它們在數據庫中的作用。精了,以前一直模模糊糊的問題這裏一下子就清晰了。這裏記錄下來。

磁盤結構

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-59qkMfuq-1593101586484)(/Users/awakeyoyoyo/Library/Application Support/typora-user-images/image-20200624232745219.png)]
抽象出來的磁盤結構:按等份分爲n個扇區(Sector),按照n個圓環分爲n個軌道(tracks)。如果我要讀去某塊區域(block)的內容需要用到(軌道號,扇區號)來進行定位。
通常將block塊取爲512字節。然後block都是從0-511的表示,則我們如果需要讀去某段字節,則需要offerset 偏移量的作用,根據block的的初始地址+偏移量即可得到某段字節的位置。
我們需要扇區號、軌道號、偏移量來讓我們找出特定塊中的特定數據。

數據如何存儲在磁盤

嘗試了好久電腦畫圖,無奈還是手畫算了。。
在這裏插入圖片描述
首先模擬一張表,這張表的字段都如上圖所示,id是10byte,而總共加起來一行記錄需要128byte的空間進行存儲,假設磁盤中的磁盤塊一塊存儲512byte,則我們可以知道一塊磁盤塊可以存儲4條記錄,則存儲100條記錄則需要25塊磁盤塊。
想象一下此時我們需要查找一個id爲98的記錄,那麼我們最差最差是不是要遍歷這25塊磁盤塊,即最差打算需要25次io讀取操作。
此時,索引的作用就體現出來了。
索引的作用就類似與書本的目錄。
在這裏插入圖片描述
如上圖所示,我們利用id建立了索引,索引的一條記錄是id和一個指向磁盤塊指定偏移量位置的指針,即指向一條完整記錄。 一條索引記錄的大小是id+指針大小,所以遠比一整條記錄來的要小,這裏假設是16byte,則一塊磁盤塊可以存儲32條記錄,則此時只需要4塊磁盤塊即可裝下該索引表。這個時候我們再需要一個id爲98的記錄,只需要遍歷4個塊,找個索引對應的指針即可找到該記錄。
多重索引
假設記錄好多,1000,10000條,則索引表也就是1000,10000條數據,這也很大啊,這時候我們只需要向上建立更大的索引,指向索引表的所存儲的塊中,這也就可以減少io遍歷次數。

看到這裏,我想大家應該有點眉目了,那麼下面用問題來理解一下。

問題

爲什麼要用建立索引?
未建立索引的時候,如果查找的時候需要將存儲數據的硬盤塊一個個讀取,找出存儲在其中的記錄的id進行比較,這樣的話效率低。
建立索引之後,可以利用一條索引記錄的大小比一條行記錄的小,讓一個硬盤塊可以存儲更多索引記錄,然後查詢的時候,只需要訪問少量的硬盤塊。
索引可以減少讀取硬盤塊的次數。提高查詢的速度。
爲什麼要用b+樹,而不是紅黑樹、b樹?
使用b+樹來實現索引,由於數據主要是存儲在硬盤中,所以查詢的主要耗費的時間在硬盤的讀取上,所以衡量使用哪種數據結構更優,就是要看誰訪問硬盤的次數少。
磁盤預讀原理:磁盤往往不是嚴格按需讀取,而是每次都會預讀,即使只需要一個字節,磁盤也會從這個位置開始,順序向後讀取一定長度的數據【這個一定的長度就是一個節點的大小設置爲16K】放入內存。
我們知道磁盤預讀原理,而b+樹的節點可以有多個key,使用b+樹可以將同一節點內的key存儲在同一塊中,這也可以只需一次i/o操作即可讀取出一個結點的所有key。並且b+樹的節點可以有多個key意味着樹的高度就會變矮,意味着查詢的時候訪問硬盤的次數也就會隨着減少。
反觀紅黑樹,一個結點只能存放一個key,則每一個結點都需要進行一次i/o操作且針對的是一個key,並且樹的高度也比較高,意味着查詢的時候需要遍歷多個結點,i/o次數多

那爲啥不是b樹呀=。=?
B+Tree區別B-Tree(B樹)的地方在於,B+Tree的非葉子結點只存儲導航信息,數據全部存儲在葉子結點處並且用鏈表連接
B+Tree的非葉子結點只存儲導航信息,意味着他可以存放更加多的key,進一步縮減了樹的高度,減少i/o次數,
而且葉子節點之間都是鏈表的結構,所以B+ Tree也是可以支持範圍查詢的,而B樹每個節點 key 和 data 在一起,則無法區間查找

末尾:

這是看着大叔視頻手寫下的一下心得,不夠嚴謹,如果有錯希望大家指出

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