日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql 二叉树表设计_mysql---B+tree索引的设计原理

發布時間:2023/12/1 数据库 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql 二叉树表设计_mysql---B+tree索引的设计原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.什么是數據庫的索引

每種查找算法都只能應用于特定的數據結構之上,例如二分查找要求被檢索數據有序,而二叉樹查找只能應用于二叉查找樹上,但是數據本身的組織結構不可能完全滿足各種數據結構(例如,理論上不可能同時將兩列都按順序進行組織),所以,在數據之外,數據庫系統還維護著滿足特定查找算法的數據結構,這些數據結構以某種方式引用(指向)數據,這樣就可以在這些數據結構上實現高級查找算法。這種數據結構,就是索引。

在向數據庫中插入新的數據時,同時也需要向數據庫索引中插入相應的索引鍵值 ,則需要向 B+樹 中插入新的鍵值。

當從數據庫中刪除數據時,同時也需要從數據庫索引中刪除相應的索引鍵值 ,則需要從 B+樹 中刪 除該鍵值

在mysql中使用的這種數據結構就是B+tree,它是B-tree的變種。

那么什么是B-tree?

2.B-tree

3.B-tree查找

模擬查找關鍵字29的過程:

根據根節點找到磁盤塊1,讀入內存。【磁盤I/O操作第1次】

比較關鍵字29在區間(17,35),找到磁盤塊1的指針P2。

根據P2指針找到磁盤塊3,讀入內存。【磁盤I/O操作第2次】

比較關鍵字29在區間(26,30),找到磁盤塊3的指針P2。

根據P2指針找到磁盤塊8,讀入內存。【磁盤I/O操作第3次】

在磁盤塊8中的關鍵字列表中找到關鍵字29。

分析上面過程,發現需要3次磁盤I/O操作,和3次內存查找操作。由于內存中的關鍵字是一個有序表結構,可以利用二分法查找提高效率。而3次磁盤I/O操作是影響整個B-Tree查找效率的決定因素。B-Tree相對于AVLTree縮減了節點個數,使每次磁盤I/O取到內存的數據都發揮了作用,從而提高了查詢效率。

4.B-tree的插入和刪除

假設需依次插入關鍵字30,26

首先通過查找確定插入的位置。由根a 起進行查找,確定30應插入的在d 節點中。由于*d 中關鍵字數目不超過2(即m-1),故第一個關鍵字插入完成:如(b)

同樣,通過查找確定關鍵字26亦應插入 d. 由于d節點關鍵字數目超過2,此時需要將 *d分裂成兩個節點,關鍵字26及其前、后兩個指針仍保留在 *d 節點中,而關鍵字37 及其前、后兩個指針存儲到新的產生的節點 *d中。同時將關鍵字30 和指示節點 *d的指針插入到其雙親的節點中。由于 *b節點中的關鍵字數目沒有超過2,則插入完成.如(c)(d)

5.B+tree

B+Tree是在B-Tree基礎上的一種優化,使其更適合實現外存儲索引結構, 即B+樹是應文件系統所需而產生的一種B-樹的變形樹。InnoDB存儲引擎就是用B+Tree實現其索引結構。

從上一節中的B-Tree結構圖中可以看到每個節點中不僅包含數據的key值,還有data值。而每一個頁的存儲空間是有限的,如果data數據較大時將會導致每個節點(即一個頁)能存儲的key的數量很小,當存儲的數據量很大時同樣會導致B-Tree的深度較大,增大查詢時的磁盤I/O次數,進而影響查詢效率。在B+Tree中,所有數據記錄節點都是按照鍵值大小順序存放在同一層的葉子節點上,而非葉子節點上只存儲key值信息,這樣可以大大加大每個節點存儲的key值數量,降低B+Tree的高度。

B+Tree相對于B-Tree有幾點不同:

非葉子節點只存儲鍵值信息。

所有葉子節點之間都有一個鏈指針。

數據記錄都存放在葉子節點中。

6.為什么使用B-Tree(B+Tree)

一般來說,索引本身也很大,不可能全部存儲在內存中,因此索引往往以索引文件的形式存儲的磁盤上。這樣的話,索引查找過程中就要產生磁盤I/O消耗,相對于內存存取,I/O存取的消耗要高幾個數量級,所以評價一個數據結構作為索引的優劣最重要的指標就是在查找過程中磁盤I/O操作次數的漸進復雜度。換句話說,索引的結構組織要盡量減少查找過程中磁盤I/O的存取次數。下面先介紹內存和磁盤存取原理,然后再結合這些原理分析B-/+Tree作為索引的效率。

局部性原理與磁盤預讀

由于存儲介質的特性,磁盤本身存取就比主存慢很多,再加上機械運動耗費,磁盤的存取速度往往是主存的幾百分分之一,因此為了提高效率,要盡量減少磁盤I/O。為了達到這個目的,磁盤往往不是嚴格按需讀取,而是每次都會預讀,即使只需要一個字節,磁盤也會從這個位置開始,順序向后讀取一定長度的數據放入內存。這樣做的理論依據是計算機科學中著名的局部性原理:

當一個數據被用到時,其附近的數據也通常會馬上被使用。

程序運行期間所需要的數據通常比較集中。

由于磁盤順序讀取的效率很高(不需要尋道時間,只需很少的旋轉時間),因此對于具有局部性的程序來說,預讀可以提高I/O效率。

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

B-/+Tree索引的性能分析

從使用磁盤I/O次數評價索引結構的優劣性:根據B-Tree的定義,可知檢索一次最多需要訪問h個結點。數據庫系統的設計者巧妙的利用了磁盤預讀原理,將一個結點的大小設為等于一個頁面,這樣每個結點只需要一次I/O就可以完全載入。為了達到這個目的,在實際實現B-Tree還需要使用如下技巧:

每次新建結點時,直接申請一個頁面的空間,這樣可以保證一個結點的大小等于一個頁面,加之計算機存儲分配都是按頁對齊的,就實現了一個node只需一次I/O。

B-Tree中一次檢索最多需要h-1次I/O(根結點常駐內存),漸進復雜度為O(h)=O(logdN)。一般實際應用中,出讀d是非常大的數字,通常超過100,因此h非常小。

綜上所述,用B-Tree作為索引結構效率是非常高的。

而紅黑樹結構,h明顯要深得多。由于邏輯上很近的結點(父子結點)物理上可能離得很遠,無法利用局部性原理。所以即使紅黑樹的I/O漸進復雜度也為O(h),但是查找效率明顯比B-Tree差得多。

B+Tree更適合外存索引,是和內結點出度d有關。從上面分析可以看到,d越大索引的性能越好,而出度的上限取決于結點內key和data的大小:dmax=floor(pagesize/(keysize+datasize+pointsize))。

floor表示向下取整。由于B+Tree內結點去掉了data域,因此可以擁有更大的出度,擁有更好的性能。

7.MyISAM索引實現

1.主鍵索引

MyISAM引擎使用B+Tree作為索引結構,葉節點的data域存放的是數據記錄的地址。

2.輔助索引

在MyISAM中,主索引和輔助索引(Secondary key)在結構上沒有任何區別,只是主索引要求key是唯一的,而輔助索引的key可以重復。如果我們在Col2上建立一個輔助索引,則此索引的結構如下圖所示:

8.InnoDB索引實現

1.InnoDB主鍵索引

InnoDB中,表數據文件本身就是按B+Tree組織的一個索引結構,這棵樹的葉節點data域保存了完整的數據記錄。這個索引的key是數據表的主鍵,因此InnoDB表數據文件本身就是主索引。

2.InnoDB輔助索引

InnoDB的所有輔助索引都引用主鍵作為data域。例如,下圖為定義在Col3上的一個輔助索引:

InnoDB存儲引擎中有頁(Page)的概念,頁是其磁盤管理的最小單位。InnoDB存儲引擎中默認每個頁的大小為16KB,可通過參數innodb_page_size將頁的大小設置為4K、8K、16K,在MySQL中可通過如下命令查看頁的大小:show variables like 'innodb_page_size';

系統從磁盤讀取數據到內存時是以磁盤塊(block)為基本單位的,位于同一個磁盤塊中的數據會被一次性讀取出來,而不是需要什么取什么。

而系統一個磁盤塊的存儲空間往往沒有這么大,因此InnoDB每次申請磁盤空間時都會是若干地址連續磁盤塊來達到頁的大小16KB。InnoDB在把磁盤數據讀入到磁盤時會以頁為基本單位,在查詢數據時如果一個頁中的每條數據都能有助于定位數據記錄的位置,這將會減少磁盤I/O次數,提高查詢效率。

.推算

InnoDB存儲引擎中頁的大小為16KB,一般表的主鍵類型為INT(占用4個字節)或BIGINT(占用8個字節),指針類型也一般為4或8個字節,也就是說一個頁(B+Tree中的一個節點)中大概存儲16KB/(8B+8B)=1K個鍵值(因為是估值,為方便計算,這里的K取值為〖10〗3)。也就是說一個深度為3的B+Tree索引可以維護103 * 10^3 * 10^3 = 10億 條記錄。

實際情況中每個節點可能不能填充滿,因此在數據庫中,B+Tree的高度一般都在24層。mysql的InnoDB存儲引擎在設計時是將根節點常駐內存的,也就是說查找某一鍵值的行記錄時最多只需要13次磁盤I/O操作。

9.數據庫中的B+Tree索引可以分為聚集索引(clustered index)和輔助索引(secondary index)

聚集索引的B+Tree中的葉子節點存放的是整張表的行記錄數據。輔助索引與聚集索引的區別在于輔助索引的葉子節點并不包含行記錄的全部數據,而是存儲相應行數據的聚集索引鍵,即主鍵。當通過輔助索引來查詢數據時,InnoDB存儲引擎會遍歷輔助索引找到主鍵,然后再通過主鍵在聚集索引中找到完整的行記錄數據。

InnoDB索引和MyISAM索引的區別:

一是主索引的區別,InnoDB的數據文件本身就是索引文件。而MyISAM的索引和數據是分開的。

二是輔助索引的區別:InnoDB的輔助索引data域存儲相應記錄主鍵的值而不是地址。而MyISAM的輔助索引和主索引沒有多大區別。

所以:

1.不建議使用過長的字段作為主鍵,因為所有輔助索引都引用主索引,過長的主索引會令輔助索引變得過大

2.用非單調的字段作為主鍵在InnoDB中不是個好主意,因為InnoDB數據文件本身是一顆B+Tree,非單調的主鍵會造成在插入新記錄時數據文件為了維持B+Tree的特性而頻繁的分裂調整,十分低效,而使用自增字段作為主鍵則是一個很好的選擇。

總結

以上是生活随笔為你收集整理的mysql 二叉树表设计_mysql---B+tree索引的设计原理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。