最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

為什么MySQL數(shù)據(jù)庫(kù)索引選擇使用B+樹?

 更新時(shí)間:2019年03月01日 11:09:09   作者:徐劉根  
今天小編就為大家分享一篇關(guān)于為什么MySQL數(shù)據(jù)庫(kù)索引選擇使用B+樹?,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧

在進(jìn)一步分析為什么MySQL數(shù)據(jù)庫(kù)索引選擇使用B+樹之前,我相信很多小伙伴對(duì)數(shù)據(jù)結(jié)構(gòu)中的樹還是有些許模糊的,因此我們由淺入深一步步探討樹的演進(jìn)過(guò)程,在一步步引出B樹以及為什么MySQL數(shù)據(jù)庫(kù)索引選擇使用B+樹!

學(xué)過(guò)數(shù)據(jù)結(jié)構(gòu)的一般對(duì)最基礎(chǔ)的樹都有所認(rèn)識(shí),因此我們就從與我們主題更為相近的二叉查找樹開始。

一、二叉查找樹

(1)二叉樹簡(jiǎn)介:

二叉查找樹也稱為有序二叉查找樹,滿足二叉查找樹的一般性質(zhì),是指一棵空樹具有如下性質(zhì):

1、任意節(jié)點(diǎn)左子樹不為空,則左子樹的值均小于根節(jié)點(diǎn)的值;

2、任意節(jié)點(diǎn)右子樹不為空,則右子樹的值均大于于根節(jié)點(diǎn)的值;

3、任意節(jié)點(diǎn)的左右子樹也分別是二叉查找樹;

4、沒(méi)有鍵值相等的節(jié)點(diǎn);


上圖為一個(gè)普通的二叉查找樹,按照中序遍歷的方式可以從小到大的順序排序輸出:2、3、5、6、7、8。

對(duì)上述二叉樹進(jìn)行查找,如查鍵值為5的記錄,先找到根,其鍵值是6,6大于5,因此查找6的左子樹,找到3;而5大于3,再找其右子樹;一共找了3次。如果按2、3、5、6、7、8的順序來(lái)找同樣需求3次。用同樣的方法在查找鍵值為8的這個(gè)記錄,這次用了3次查找,而順序查找需要6次。計(jì)算平均查找次數(shù)得:順序查找的平均查找次數(shù)為(1+2+3+4+5+6)/ 6 = 3.3次,二叉查找樹的平均查找次數(shù)為(3+3+3+2+2+1)/6=2.3次。二叉查找樹的平均查找速度比順序查找來(lái)得更快。

(2)局限性及應(yīng)用

一個(gè)二叉查找樹是由n個(gè)節(jié)點(diǎn)隨機(jī)構(gòu)成,所以,對(duì)于某些情況,二叉查找樹會(huì)退化成一個(gè)有n個(gè)節(jié)點(diǎn)的線性鏈。如下圖:


大家看上圖,如果我們的根節(jié)點(diǎn)選擇是最小或者最大的數(shù),那么二叉查找樹就完全退化成了線性結(jié)構(gòu)。上圖中的平均查找次數(shù)為(1+2+3+4+5+5)/6=3.16次,和順序查找差不多。顯然這個(gè)二叉樹的查詢效率就很低,因此若想最大性能的構(gòu)造一個(gè)二叉查找樹,需要這個(gè)二叉樹是平衡的(這里的平衡從一個(gè)顯著的特點(diǎn)可以看出這一棵樹的高度比上一個(gè)輸?shù)母叨纫螅谙嗤?jié)點(diǎn)的情況下也就是不平衡),從而引出了一個(gè)新的定義-平衡二叉樹AVL。

二、AVL樹

(1)簡(jiǎn)介

AVL樹是帶有平衡條件的二叉查找樹,一般是用平衡因子差值判斷是否平衡并通過(guò)旋轉(zhuǎn)來(lái)實(shí)現(xiàn)平衡,左右子樹樹高不超過(guò)1,和紅黑樹相比,它是嚴(yán)格的平衡二叉樹,平衡條件必須滿足(所有節(jié)點(diǎn)的左右子樹高度差不超過(guò)1)。不管我們是執(zhí)行插入還是刪除操作,只要不滿足上面的條件,就要通過(guò)旋轉(zhuǎn)來(lái)保持平衡,而旋轉(zhuǎn)是非常耗時(shí)的,由此我們可以知道AVL樹適合用于插入刪除次數(shù)比較少,但查找多的情況。

從上面是一個(gè)普通的平衡二叉樹,這張圖我們可以看出,任意節(jié)點(diǎn)的左右子樹的平衡因子差值都不會(huì)大于1。

(2)局限性

由于維護(hù)這種高度平衡所付出的代價(jià)比從中獲得的效率收益還大,故而實(shí)際的應(yīng)用不多,更多的地方是用追求局部而不是非常嚴(yán)格整體平衡的紅黑樹。當(dāng)然,如果應(yīng)用場(chǎng)景中對(duì)插入刪除不頻繁,只是對(duì)查找要求較高,那么AVL還是較優(yōu)于紅黑樹。

(3)應(yīng)用

1、Windows NT內(nèi)核中廣泛存在;

三、紅黑樹

(1)簡(jiǎn)介

一種二叉查找樹,但在每個(gè)節(jié)點(diǎn)增加一個(gè)存儲(chǔ)位表示節(jié)點(diǎn)的顏色,可以是red或black。通過(guò)對(duì)任何一條從根到葉子的路徑上各個(gè)節(jié)點(diǎn)著色的方式的限制,紅黑樹確保沒(méi)有一條路徑會(huì)比其它路徑長(zhǎng)出兩倍。它是一種弱平衡二叉樹(由于是若平衡,可以推出,相同的節(jié)點(diǎn)情況下,AVL樹的高度低于紅黑樹),相對(duì)于要求嚴(yán)格的AVL樹來(lái)說(shuō),它的旋轉(zhuǎn)次數(shù)變少,所以對(duì)于搜索、插入、刪除操作多的情況下,我們就用紅黑樹。

(2)性質(zhì)

1、每個(gè)節(jié)點(diǎn)非紅即黑;

 2、根節(jié)點(diǎn)是黑的;

3、每個(gè)葉節(jié)點(diǎn)(葉節(jié)點(diǎn)即樹尾端NULL指針或NULL節(jié)點(diǎn))都是黑的;

4、如果一個(gè)節(jié)點(diǎn)是紅的,那么它的兩兒子都是黑的;

5、對(duì)于任意節(jié)點(diǎn)而言,其到葉子點(diǎn)樹NULL指針的每條路徑都包含相同數(shù)目的黑節(jié)點(diǎn);

6、每條路徑都包含相同的黑節(jié)點(diǎn);

(3)應(yīng)用

1、廣泛用于C++的STL中,Map和Set都是用紅黑樹實(shí)現(xiàn)的;

2、著名的Linux進(jìn)程調(diào)度Completely Fair Scheduler,用紅黑樹管理進(jìn)程控制塊,進(jìn)程的虛擬內(nèi)存區(qū)域都存儲(chǔ)在一顆紅黑樹上,每個(gè)虛擬地址區(qū)域都對(duì)應(yīng)紅黑樹的一個(gè)節(jié)點(diǎn),左指針指向相鄰的地址虛擬存儲(chǔ)區(qū)域,右指針指向相鄰的高地址虛擬地址空間;

3、IO多路復(fù)用epoll的實(shí)現(xiàn)采用紅黑樹組織管理sockfd,以支持快速的增刪改查;

4、Nginx中用紅黑樹管理timer,因?yàn)榧t黑樹是有序的,可以很快的得到距離當(dāng)前最小的定時(shí)器;

5、Java中TreeMap的實(shí)現(xiàn);

四、B/B+樹

說(shuō)了上述的三種樹:二叉查找樹、AVL和紅黑樹,似乎我們還沒(méi)有摸到MySQL為什么要使用B+樹作為索引的實(shí)現(xiàn),不要急,接下來(lái)我們就先探討一下什么是B樹。

(1)簡(jiǎn)介

我們?cè)贛ySQL中的數(shù)據(jù)一般是放在磁盤中的,讀取數(shù)據(jù)的時(shí)候肯定會(huì)有訪問(wèn)磁盤的操作,磁盤中有兩個(gè)機(jī)械運(yùn)動(dòng)的部分,分別是盤片旋轉(zhuǎn)和磁臂移動(dòng)。盤片旋轉(zhuǎn)就是我們市面上所提到的多少轉(zhuǎn)每分鐘,而磁盤移動(dòng)則是在盤片旋轉(zhuǎn)到指定位置以后,移動(dòng)磁臂后開始進(jìn)行數(shù)據(jù)的讀寫。那么這就存在一個(gè)定位到磁盤中的塊的過(guò)程,而定位是磁盤的存取中花費(fèi)時(shí)間比較大的一塊,畢竟機(jī)械運(yùn)動(dòng)花費(fèi)的時(shí)候要遠(yuǎn)遠(yuǎn)大于電子運(yùn)動(dòng)的時(shí)間。當(dāng)大規(guī)模數(shù)據(jù)存儲(chǔ)到磁盤中的時(shí)候,顯然定位是一個(gè)非常花費(fèi)時(shí)間的過(guò)程,但是我們可以通過(guò)B樹進(jìn)行優(yōu)化,提高磁盤讀取時(shí)定位的效率。

為什么B類樹可以進(jìn)行優(yōu)化呢?我們可以根據(jù)B類樹的特點(diǎn),構(gòu)造一個(gè)多階的B類樹,然后在盡量多的在結(jié)點(diǎn)上存儲(chǔ)相關(guān)的信息,保證層數(shù)盡量的少,以便后面我們可以更快的找到信息,磁盤的I/O操作也少一些,而且B類樹是平衡樹,每個(gè)結(jié)點(diǎn)到葉子結(jié)點(diǎn)的高度都是相同,這也保證了每個(gè)查詢是穩(wěn)定的。

總的來(lái)說(shuō),B/B+樹是為了磁盤或其它存儲(chǔ)設(shè)備而設(shè)計(jì)的一種平衡多路查找樹(相對(duì)于二叉,B樹每個(gè)內(nèi)節(jié)點(diǎn)有多個(gè)分支),與紅黑樹相比,在相同的的節(jié)點(diǎn)的情況下,一顆B/B+樹的高度遠(yuǎn)遠(yuǎn)小于紅黑樹的高度(在下面B/B+樹的性能分析中會(huì)提到)。B/B+樹上操作的時(shí)間通常由存取磁盤的時(shí)間和CPU計(jì)算時(shí)間這兩部分構(gòu)成,而CPU的速度非常快,所以B樹的操作效率取決于訪問(wèn)磁盤的次數(shù),關(guān)鍵字總數(shù)相同的情況下B樹的高度越小,磁盤I/O所花的時(shí)間越少。

注意B-樹就是B樹,-只是一個(gè)符號(hào)。

(2)B樹的性質(zhì)

1、定義任意非葉子結(jié)點(diǎn)最多只有M個(gè)兒子,且M>2;

2、根結(jié)點(diǎn)的兒子數(shù)為[2, M];

3、除根結(jié)點(diǎn)以外的非葉子結(jié)點(diǎn)的兒子數(shù)為[M/2, M];

4、每個(gè)結(jié)點(diǎn)存放至少M(fèi)/2-1(取上整)和至多M-1個(gè)關(guān)鍵字;(至少2個(gè)關(guān)鍵字)

5、非葉子結(jié)點(diǎn)的關(guān)鍵字個(gè)數(shù)=指向兒子的指針個(gè)數(shù)-1;

6、非葉子結(jié)點(diǎn)的關(guān)鍵字:K[1], K[2], …, K[M-1];且K[i] < K[i+1];

7、非葉子結(jié)點(diǎn)的指針:P[1], P[2], …, P[M];其中P[1]指向關(guān)鍵字小于K[1]的子樹,P[M]指向關(guān)鍵字大于K[M-1]的子樹,其它P[i]指向關(guān)鍵字屬于(K[i-1], K[i])的子樹;

8、所有葉子結(jié)點(diǎn)位于同一層;


這里只是一個(gè)簡(jiǎn)單的B樹,在實(shí)際中B樹節(jié)點(diǎn)中關(guān)鍵字很多的,上面的圖中比如35節(jié)點(diǎn),35代表一個(gè)key(索引),而小黑塊代表的是這個(gè)key所指向的內(nèi)容在內(nèi)存中實(shí)際的存儲(chǔ)位置,是一個(gè)指針。

五、B+樹

(1)簡(jiǎn)介

B+樹是應(yīng)文件系統(tǒng)所需而產(chǎn)生的一種B樹的變形樹(文件的目錄一級(jí)一級(jí)索引,只有最底層的葉子節(jié)點(diǎn)(文件)保存數(shù)據(jù))非葉子節(jié)點(diǎn)只保存索引,不保存實(shí)際的數(shù)據(jù),數(shù)據(jù)都保存在葉子節(jié)點(diǎn)中,這不就是文件系統(tǒng)文件的查找嗎?

我們就舉個(gè)文件查找的例子:有3個(gè)文件夾a、b、c, a包含b,b包含c,一個(gè)文件yang.c,a、b、c就是索引(存儲(chǔ)在非葉子節(jié)點(diǎn)), a、b、c只是要找到的yang.c的key,而實(shí)際的數(shù)據(jù)yang.c存儲(chǔ)在葉子節(jié)點(diǎn)上。

所有的非葉子節(jié)點(diǎn)都可以看成索引部分!

(2)B+樹的性質(zhì)(下面提到的都是和B樹不相同的性質(zhì))

1、非葉子節(jié)點(diǎn)的子樹指針與關(guān)鍵字個(gè)數(shù)相同;

2、非葉子節(jié)點(diǎn)的子樹指針p[i],指向關(guān)鍵字值屬于[k[i],k[i+1]]的子樹.(B樹是開區(qū)間,也就是說(shuō)B樹不允許關(guān)鍵字重復(fù),B+樹允許重復(fù));

3、為所有葉子節(jié)點(diǎn)增加一個(gè)鏈指針;

4、所有關(guān)鍵字都在葉子節(jié)點(diǎn)出現(xiàn)(稠密索引). (且鏈表中的關(guān)鍵字恰好是有序的);

5、非葉子節(jié)點(diǎn)相當(dāng)于是葉子節(jié)點(diǎn)的索引(稀疏索引),葉子節(jié)點(diǎn)相當(dāng)于是存儲(chǔ)(關(guān)鍵字)數(shù)據(jù)的數(shù)據(jù)層;

6、更適合于文件系統(tǒng);

非葉子節(jié)點(diǎn)(比如5,28,65)只是一個(gè)key(索引),實(shí)際的數(shù)據(jù)存在葉子節(jié)點(diǎn)上(5,8,9)才是真正的數(shù)據(jù)或指向真實(shí)數(shù)據(jù)的指針。

(3)應(yīng)用  

1、B和B+樹主要用在文件系統(tǒng)以及數(shù)據(jù)庫(kù)做索引,比如MySQL;

六、B/B+樹性能分析

n個(gè)節(jié)點(diǎn)的平衡二叉樹的高度為H(即logn),而n個(gè)節(jié)點(diǎn)的B/B+樹的高度為logt((n+1)/2)+1;

若要作為內(nèi)存中的查找表,B樹卻不一定比平衡二叉樹好,尤其當(dāng)m較大時(shí)更是如此。因?yàn)椴檎也僮鰿PU的時(shí)間在B-樹上是O(mlogtn)=O(lgn(m/lgt)),而m/lgt>1;所以m較大時(shí)O(mlogtn)比平衡二叉樹的操作時(shí)間大得多。因此在內(nèi)存中使用B樹必須取較小的m。(通常取最小值m=3,此時(shí)B-樹中每個(gè)內(nèi)部結(jié)點(diǎn)可以有2或3個(gè)孩子,這種3階的B-樹稱為2-3樹)。

七、為什么說(shuō)B+樹比B樹更適合數(shù)據(jù)庫(kù)索引?

1、 B+樹的磁盤讀寫代價(jià)更低:B+樹的內(nèi)部節(jié)點(diǎn)并沒(méi)有指向關(guān)鍵字具體信息的指針,因此其內(nèi)部節(jié)點(diǎn)相對(duì)B樹更小,如果把所有同一內(nèi)部節(jié)點(diǎn)的關(guān)鍵字存放在同一盤塊中,那么盤塊所能容納的關(guān)鍵字?jǐn)?shù)量也越多,一次性讀入內(nèi)存的需要查找的關(guān)鍵字也就越多,相對(duì)IO讀寫次數(shù)就降低了。

2、B+樹的查詢效率更加穩(wěn)定:由于非終結(jié)點(diǎn)并不是最終指向文件內(nèi)容的結(jié)點(diǎn),而只是葉子結(jié)點(diǎn)中關(guān)鍵字的索引。所以任何關(guān)鍵字的查找必須走一條從根結(jié)點(diǎn)到葉子結(jié)點(diǎn)的路。所有關(guān)鍵字查詢的路徑長(zhǎng)度相同,導(dǎo)致每一個(gè)數(shù)據(jù)的查詢效率相當(dāng)。

3、由于B+樹的數(shù)據(jù)都存儲(chǔ)在葉子結(jié)點(diǎn)中,分支結(jié)點(diǎn)均為索引,方便掃庫(kù),只需要掃一遍葉子結(jié)點(diǎn)即可,但是B樹因?yàn)槠浞种ЫY(jié)點(diǎn)同樣存儲(chǔ)著數(shù)據(jù),我們要找到具體的數(shù)據(jù),需要進(jìn)行一次中序遍歷按序來(lái)掃,所以B+樹更加適合在區(qū)間查詢的情況,所以通常B+樹用于數(shù)據(jù)庫(kù)索引。

PS:我在知乎上看到有人是這樣說(shuō)的,我感覺(jué)說(shuō)的也挺有道理的:

他們認(rèn)為數(shù)據(jù)庫(kù)索引采用B+樹的主要原因是:B樹在提高了IO性能的同時(shí)并沒(méi)有解決元素遍歷的我效率低下的問(wèn)題,正是為了解決這個(gè)問(wèn)題,B+樹應(yīng)用而生。B+樹只需要去遍歷葉子節(jié)點(diǎn)就可以實(shí)現(xiàn)整棵樹的遍歷。而且在數(shù)據(jù)庫(kù)中基于范圍的查詢是非常頻繁的,而B樹不支持這樣的操作或者說(shuō)效率太低。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請(qǐng)查看下面相關(guān)鏈接

相關(guān)文章

  • 圖文詳解Mysql中如何查看Sql語(yǔ)句的執(zhí)行時(shí)間

    圖文詳解Mysql中如何查看Sql語(yǔ)句的執(zhí)行時(shí)間

    寫程序的人往往需要分析所寫的SQL語(yǔ)句是否已經(jīng)優(yōu)化過(guò)了,服務(wù)器的響應(yīng)時(shí)間有多快,所以下面這篇文章主要給大家介紹了關(guān)于Mysql中如何查看Sql語(yǔ)句的執(zhí)行時(shí)間的相關(guān)資料,需要的朋友可以參考下
    2021-12-12
  • MySQL索引之聚集索引介紹

    MySQL索引之聚集索引介紹

    在MySQL中,InnoDB引擎表是(聚集)索引組織表(clustered index organize table),而MyISAM引擎表則是堆組織表(heap organize table)
    2015-12-12
  • Windows10 mysql 8.0.12 非安裝版配置啟動(dòng)方法

    Windows10 mysql 8.0.12 非安裝版配置啟動(dòng)方法

    這篇文章主要為大家詳細(xì)介紹了Windows10 mysql 8.0.12 非安裝版配置啟動(dòng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-05-05
  • mysql安裝數(shù)據(jù)庫(kù)初始化失敗問(wèn)題解決方法保姆級(jí)教程

    mysql安裝數(shù)據(jù)庫(kù)初始化失敗問(wèn)題解決方法保姆級(jí)教程

    這篇文章主要給大家介紹了關(guān)于mysql安裝數(shù)據(jù)庫(kù)初始化失敗問(wèn)題解決方法保姆級(jí)教程,包括更改電腦名稱、確保防火墻設(shè)置、清理殘留文件、檢查權(quán)限和配置文件等,需要的朋友可以參考下
    2025-01-01
  • 最新評(píng)論

    赤壁市| 延津县| 买车| 三原县| 文水县| 隆化县| 商南县| 获嘉县| 临汾市| 宽甸| 孝昌县| 汾阳市| 内黄县| 赤水市| 南华县| 兰西县| 株洲县| 尼玛县| 汪清县| 读书| 宁阳县| 明溪县| 延津县| 浙江省| 彭水| 承德县| 永昌县| 江华| 申扎县| 东莞市| 阳春市| 手游| 镇远县| 商都县| 科技| 长沙县| 碌曲县| 石门县| 巩义市| 城市| 新沂市|