一文了解mysql索引的數(shù)據(jù)結(jié)構(gòu)為什么要用B+樹(shù)
前提: 以下的一些數(shù)據(jù)結(jié)構(gòu)大家需提前知道,否則看起來(lái)會(huì)比較有困難,大家也可以按照本文所提到的知識(shí)點(diǎn)去主動(dòng)查閱學(xué)習(xí)。
1. Hash表?No
因考慮到在數(shù)據(jù)檢索的過(guò)程中經(jīng)常會(huì)有范圍的查詢(如下),而hash表不能提供這種功能。
SELECT * FROM hero WHERE age>5 AND age<20;
使用哈希算法實(shí)現(xiàn)的索引雖然可以做到快速檢索數(shù)據(jù),但是沒(méi)辦法做數(shù)據(jù)高效范圍查找,因此哈希索引是不適合作為 Mysql 的底層索引的數(shù)據(jù)結(jié)構(gòu)。
2. 二叉查找樹(shù)(BST)?No
二叉查找樹(shù)(Binary Search Tree)雖然可以達(dá)到范圍搜索,但是在樹(shù)的插入過(guò)程中,如果插入的數(shù)據(jù)本來(lái)就是有順序的,那么就會(huì)形成一條鏈(如下),它的最壞情況是O(n)。

3. 紅黑樹(shù)?No
紅黑樹(shù)雖然看似達(dá)到了平衡狀態(tài),但是也會(huì)有極端情況存在,和上述BST樹(shù)一樣,雖然不會(huì)成為鏈狀,但是紅黑樹(shù)會(huì)存在右傾的現(xiàn)象。

在數(shù)據(jù)庫(kù)中的基本主鍵自增操作,主鍵一般都是數(shù)百萬(wàn)數(shù)千萬(wàn)的,如果紅黑樹(shù)存在這種問(wèn)題,對(duì)于查找性能而言也是巨大的消耗,我們數(shù)據(jù)庫(kù)不可能忍受這種無(wú)意義的等待的。
4. 平衡二叉樹(shù)(AVL)?差那么二點(diǎn)意思
平衡二叉樹(shù),英文翻譯為Balanced Binary Tree,為啥叫AVL呢? AVL 是大學(xué)教授G.M. Adelson-Velsky 和 E.M. Landis 名稱的縮寫,他們提出的平衡二叉樹(shù)的概念,為了紀(jì)念他們,將平衡二叉樹(shù)稱為 AVL樹(shù)。
AVL樹(shù)本質(zhì)上是一顆二叉查找樹(shù),但是它又具有以下特點(diǎn):
- 它是一棵空樹(shù)或它的左右兩個(gè)子樹(shù)的高度差的絕對(duì)值不超過(guò)1,
- 左右兩個(gè)子樹(shù)也都是一棵平衡二叉樹(shù)。
它不存在紅黑樹(shù)這種右傾的現(xiàn)象,也具備數(shù)據(jù)高效范圍查找的能力,但是數(shù)據(jù)庫(kù)查詢數(shù)據(jù)的瓶頸在于磁盤的IO,樹(shù)節(jié)點(diǎn)在磁盤空間中存儲(chǔ)可能是不連續(xù)的,假設(shè)我們一次IO讀取一個(gè)樹(shù)的節(jié)點(diǎn),此次讀入內(nèi)存的這頁(yè)中沒(méi)有其他樹(shù)的節(jié)點(diǎn),那么每讀取一個(gè)樹(shù)的節(jié)點(diǎn),就要進(jìn)行一次IO,這是多么消耗時(shí)間啊,所以我們?cè)O(shè)計(jì)數(shù)據(jù)庫(kù)索引時(shí)需要首先考慮怎么盡可能減少磁盤 IO 的次數(shù)。 磁盤讀取依靠的是機(jī)械運(yùn)動(dòng),分為尋道時(shí)間、旋轉(zhuǎn)延遲、傳輸時(shí)間三個(gè)部分,這三個(gè)部分耗時(shí)相加就是一次磁盤IO的時(shí)間;這個(gè)花費(fèi)的時(shí)間成本是內(nèi)存訪問(wèn)的十幾萬(wàn)倍左右。 正是由于磁盤IO是非常昂貴的操作,所以計(jì)算機(jī)操作系統(tǒng)對(duì)此做了優(yōu)化:預(yù)讀;每一次IO時(shí),不僅僅把當(dāng)前磁盤地址的數(shù)據(jù)加載到內(nèi)存,同時(shí)也把相鄰數(shù)據(jù)也加載到內(nèi)存緩沖區(qū)中。因?yàn)榫植款A(yù)讀原理說(shuō)明:當(dāng)訪問(wèn)一個(gè)地址數(shù)據(jù)的時(shí)候,與其相鄰的數(shù)據(jù)很快也會(huì)被訪問(wèn)到。每次磁盤IO讀取的數(shù)據(jù)我們稱之為一頁(yè)(page)。一頁(yè)的大小與操作系統(tǒng)有關(guān),一般為4k或者8k。這也就意味著讀取一頁(yè)內(nèi)數(shù)據(jù)的時(shí)候,實(shí)際上發(fā)生了一次磁盤IO。
相關(guān)術(shù)語(yǔ)解釋:
扇區(qū)(sector):
- 磁盤上的每個(gè)磁道被等分成多個(gè)弧段,這個(gè)弧段便稱作扇區(qū)(sector)。
扇區(qū)是磁盤物理層面的名稱,它是實(shí)際發(fā)生讀寫的最底層。
磁盤塊(IO Block):
- 操作系統(tǒng)不與扇區(qū)直接進(jìn)行交互,因?yàn)橐话闱闆r下一個(gè)扇區(qū)是512byte,如果1T去用512byte進(jìn)行劃分,那劃分的地址空間太多了,為了讓操作系統(tǒng)能夠?qū)ぶ返礁蟮牡刂房臻g,操作系統(tǒng)將相鄰的扇區(qū)組合在一起,形成一個(gè)塊,對(duì)塊進(jìn)行管理。每個(gè)磁盤塊可以包括 2、4、8、16、32 或 64 個(gè)扇區(qū),這便是磁盤塊(IO Block)。
磁盤塊是操作系統(tǒng)中出現(xiàn)的名稱,文件系統(tǒng)讀寫數(shù)據(jù)的最小單位,它同時(shí)也被叫做磁盤簇。
頁(yè)(page):
頁(yè)是內(nèi)存中出現(xiàn)的名稱,它是內(nèi)存的最小存儲(chǔ)單位,頁(yè)的大小通常為磁盤塊大小的 2^n 倍。
5. B-tree(B-樹(shù)也稱B樹(shù))?差那么一點(diǎn)意思
B樹(shù)是一種平衡的多叉樹(shù),B樹(shù)相比于平衡二叉樹(shù)(AVL),它能夠在單個(gè)節(jié)點(diǎn)中存儲(chǔ)大量鍵,也降低了樹(shù)的高度,從而減少了IO的次數(shù)。

B樹(shù)的節(jié)點(diǎn)中存儲(chǔ)的是數(shù)據(jù),單個(gè)節(jié)點(diǎn)存儲(chǔ)的內(nèi)容還是太少了,如何讓一個(gè)節(jié)點(diǎn)存儲(chǔ)的內(nèi)容更多呢?B+樹(shù)它來(lái)了。
6. B+樹(shù)
在節(jié)點(diǎn)中存儲(chǔ)某段數(shù)據(jù)的首地址,并且B+樹(shù)的葉子節(jié)點(diǎn)用了一個(gè)鏈表串聯(lián)起來(lái),便于范圍查找。

B+樹(shù)高度降低,減少了磁盤 IO。其次,B+樹(shù)的葉子節(jié)點(diǎn)是真正數(shù)據(jù)存儲(chǔ)的地方,葉子節(jié)點(diǎn)用了鏈表連接起來(lái),這個(gè)鏈表本身就是有序的,在數(shù)據(jù)范圍查找時(shí),更具備效率。因此 Mysql 的索引用的就是 B+樹(shù),B+樹(shù)在查找效率、范圍查找中都有著非常不錯(cuò)的性能。
到此這篇關(guān)于一文了解mysql索引的數(shù)據(jù)結(jié)構(gòu)為什么用B+樹(shù)的文章就介紹到這了,更多相關(guān)mysql B+樹(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL創(chuàng)建和刪除數(shù)據(jù)表的命令及語(yǔ)法詳解
這篇文章主要介紹了MySQL創(chuàng)建和刪除數(shù)據(jù)表的命令及語(yǔ)法,是MySQL入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-11-11
MySQL中VARCHAR與CHAR格式數(shù)據(jù)的區(qū)別
char是一種固定長(zhǎng)度的類型,varchar則是一種可變長(zhǎng)度的類型,那么他們具體使用過(guò)程中有什么區(qū)別嗎2015-09-09
MySQL和Redis實(shí)現(xiàn)二級(jí)緩存的方法詳解
這篇文章主要給大家介紹了關(guān)于MySQL和Redis實(shí)現(xiàn)二級(jí)緩存的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-02-02
mysql數(shù)據(jù)庫(kù)limit的四種用法小結(jié)
mysql數(shù)據(jù)庫(kù)中l(wèi)imit子句可以被用于強(qiáng)制select語(yǔ)句返回指定的記錄數(shù),本文主要介紹了mysql數(shù)據(jù)庫(kù)limit的四種用法小結(jié),感興趣的可以了解一下2023-10-10
淺談Mysql insert on duplicate key 死鎖問(wèn)
本文介紹了在并發(fā)場(chǎng)景下的 insert on duplicate key update sql 出現(xiàn)的死鎖,經(jīng)過(guò)分析發(fā)現(xiàn)這種sql確實(shí)比較容易造成死鎖,這篇文章就從分析死鎖展開(kāi),到最終如何解決這樣的問(wèn)題 分享相應(yīng)的思路,感興趣的可以了解一下2022-05-05
mysql數(shù)據(jù)庫(kù)分區(qū)的使用
MySQL分區(qū)技術(shù)通過(guò)將大表分割成多個(gè)較小片段,提高查詢性能、管理效率和數(shù)據(jù)存儲(chǔ)效率,本文就來(lái)介紹一下mysql數(shù)據(jù)庫(kù)分區(qū)的使用,感興趣的可以了解一下2025-01-01

