要了解數據庫索引的底層原理,我們就得先了解一種叫樹的數據結構,而樹中很經典的一種數據結構就是二叉樹!所以下面我們就從二叉樹到平衡二叉樹,再到B-樹,最后到B+樹來一步一步了解數據庫索引底層的原理!
二叉樹(Binary Search Trees)
二叉樹是每個結點最多有兩個子樹的樹結構。通常子樹被稱作“左子樹”(left subtree)和“右子樹”(right subtree)。二叉樹常被用於實現二叉查找樹和二叉堆。二叉樹有如下特性:
1、每個結點都包含一個元素以及n個子樹,這里0≤n≤2。
2、左子樹和右子樹是有順序的,次序不能任意顛倒。左子樹的值要小於父結點,右子樹的值要大於父結點
平衡二叉樹 (AVL Trees)
平衡二叉樹是一種特殊的二叉樹,所以他也滿足前面說到的二叉樹的兩個特性,同時還有一個特性:
它的左右兩個子樹的高度差的絕對值不超過1,並且左右兩個子樹都是一棵平衡二叉樹。
B-Tree
這顆矮胖的樹就是B-Tree,注意中間是杠精的杠而不是減,所以也不要讀成B減Tree了~
那B-Tree有哪些特性呢?一棵m階的B-Tree有如下特性:
1、每個結點最多m個子結點。
2、除了根結點和葉子結點外,每個結點最少有m/2(向上取整)個子結點。
3、如果根結點不是葉子結點,那根結點至少包含兩個子結點。
4、所有的葉子結點都位於同一層。
5、每個結點都包含k個元素(關鍵字),這里m/2≤k<m,這里m 2向下取整。
7、每個元素(關鍵字)字左結點的值,都小於或等於該元素(關鍵字)。右結點的值都大於或等於該元素(關鍵字)。
B+Tree
B+Tree是在B-Tree基礎上的一種優化,使其更適合實現外存儲索引結構。B+Tree與B-Tree的結構很像,但是也有幾個自己的特性:
1、所有的非葉子節點只存儲關鍵字信息。
2、所有衛星數據(具體數據)都存在葉子結點中。
3、所有的葉子結點中包含了全部元素的信息。
4、所有葉子節點之間都有一個鏈指針。
Hash數據結構存儲
在mysql中建立索引的時候,可以選擇是用hash,還是B+Tree.Hash是這樣的,當你存入索引的時候會通過hash算法生成一個hashCode,在存入內存的時候就將你的這個hashCode和地址指針配對存入。這樣做的好處就是當你在查詢的時候,能夠快速的定位,根本不需要去比較查找,只要根據這個值通過hash算法就可以找到你要的數據了。但是這種結構在實際應用中基本上是很少用的(至少我是沒遇到過),為什么呢?因為在實際的應用中我們的sql語句查詢用的比較多的是范圍查找而不是精准定位。
綜上所述,B+Tree成為了mysql,oracle等數據庫的底層數據結構的不二之選。
聚集(clustered)索引,也叫聚簇索引。
定義:數據行的物理順序與列值(一般是主鍵的那一列)的邏輯順序相同,一個表中只能擁有一個聚集索引。
聚集索引實際存放的示意圖
從上圖可以看出聚集索引的好處了,索引的葉子節點就是對應的數據節點(MySQL的MyISAM除外,此存儲引擎的聚集索引和非聚集索引只多了個唯一約束,其他沒什么區別),可以直接獲取到對應的全部列的數據,而非聚集索引在索引沒有覆蓋到對應的列的時候需要進行二次查詢,后面會詳細講。因此在查詢方面,聚集索引的速度往往會更占優勢。
非聚集索引
非聚集(unclustered)索引。
定義:該索引中索引的邏輯順序與磁盤上行的物理存儲順序不同,一個表中可以擁有多個非聚集索引。
其實按照定義,除了聚集索引以外的索引都是非聚集索引,只是人們想細分一下非聚集索引,分成普通索引,唯一索引,全文索引。如果非要把非聚集索引類比成現實生活中的東西,那么非聚集索引就像新華字典的偏旁字典,他結構順序與實際存放順序不一定一致
非聚集索引葉子節點還是索引節點。
非聚集索引和聚集索引一樣, 同樣是采用平衡樹作為索引的數據結構。索引樹結構中各節點的值來自於表中的索引字段, 假如給user表的name字段加上索引 , 那么索引就是由name字段中的值構成,在數據改變時, DBMS需要一直維護索引結構的正確性。如果給表中多個字段加上索引 , 那么就會出現多個獨立的索引結構,每個索引(非聚集索引)互相之間不存在關聯。 如下圖
每次給字段建一個新索引, 字段中的數據就會被復制一份出來, 用於生成索引。 因此, 給表添加索引,會增加表的體積, 占用磁盤存儲空間。
非聚集索引和聚集索引的區別在於, 通過聚集索引可以查到需要查找的數據, 而通過非聚集索引可以查到記錄對應的主鍵值 , 再使用主鍵的值通過聚集索引查找到需要的數據,如下圖
不管以任何方式查詢表, 最終都會利用主鍵通過聚集索引來定位到數據, 聚集索引(主鍵)是通往真實數據所在的唯一路徑。
然而, 有一種例外可以不使用聚集索引就能查詢出所需要的數據, 這種非主流的方法 稱之為「覆蓋索引」查詢, 也就是平時所說的復合索引或者多字段索引查詢。 文章上面的內容已經指出, 當為字段建立索引以后, 字段中的內容會被同步到索引之中, 如果為一個索引指定兩個字段, 那么這個兩個字段的內容都會被同步至索引之中。
如果查詢的字段中包含了其它索引中不存在的字段,那么就會進行二次查詢。
其它詳情參考:https://www.cnblogs.com/s-b-b/p/8334593.html https://www.cnblogs.com/yatou-blog/articles/lipingyatou.html