提出的問題
什么情況下創建索引,什么時候不需要索引?
索引的種類有哪些?
什么是索引
索引就是幫助數據庫管理系統高效獲取數據的數據結構,就好比一本書的目錄,它可以幫我們快速進行特定值的定位與查找,從而加快數據查詢的效率。
索引的種類
從功能邏輯上划分
- 普通索引是基礎的索引,沒有任何約束,主要用於提高查詢效率
- 唯一索引就是在普通索引的基礎上增加了數據唯一性的約束,在一張數據表里可以有多個唯一索引
- 主鍵索引在唯一索引的基礎上增加了不為空的約束,也就是 NOT NULL+UNIQUE,一張表里最多只有一個主鍵索引
- 全文索引用的不多,MySQL 自帶的全文索引只支持英文。我們通常可以采用專門的全文搜索引擎,比如 ES(ElasticSearch) 和 Solr
從物理實現方式分
- 聚集索引
- 聚集索引可以按照主鍵來排序存儲數據,這樣在查找行的時候非常有效
- 非聚集索引
- 在數據庫系統會有單獨的存儲空間存放非聚集索引,這些索引項是按照順序存儲的,但索引項指向的內容是隨機存儲的。也就是說系統會進行兩次查找,第一次先找到索引,第二次找到索引對應的位置取出數據行,是維護單獨的索引表(只維護索引,不維護索引指向的數據。
- 區別
- 聚集索引的葉子節點存儲的就是我們的數據記錄,非聚集索引的葉子節點存儲的是數據位置。非聚集索引不會影響數據表的物理存儲順序。
- 一個表只能有一個聚集索引,因為只能有一種排序存儲的方式,但可以有多個非聚集索引,也就是多個索引目錄提供數據檢索。
- 使用聚集索引的時候,數據的查詢效率高,但如果對數據進行插入,刪除,更新等操作,效率會比非聚集索引低
索引的原理
索引為什么要存儲在硬盤上
數據庫服務器有兩種存儲介質,硬盤和內存,存儲在內存時如果發生故障比如斷點什么的,容易造成數據丟失,存儲在磁盤上,會有很多的IO,我們知道磁盤IO是會耗時的,如果讓索引的數據結構盡可能的減少磁盤IO操作,那么耗時就會大大減少。
從二叉樹到B+樹
支持快速查找的數據結構有跳表、hash表、二叉樹搜索樹,跳表支持區間查找,hash表不支持區間查詢,二叉樹搜索樹不支持按照區間快速查詢,但是二叉樹搜索樹的不斷演進和改造滿足了索引對數據結構的要求,下面來看看二叉搜索到B+樹的演進歷程。
二叉搜索樹是一種比較特別大的二叉樹,每個節點的左子節點都小於父節點,右子節點大於父節點,查找一個接地那的時間復雜度是O(log2n)。
iShot 2020-03-05 22.55.45.png
但是隨着不斷往樹上添加節點,可能會造成一種現象,某一條路徑會不斷增加,最后二叉樹退化成了一個鏈表,時間復雜度變成了O(n)。
如果能讓左右子樹之間的高度差不大,還能繼續維持二叉搜索樹的特性,大牛們提出了平衡二叉樹這種結構,他讓每個節點的左右子樹高度差不能超過1,這屬於嚴格平衡的,比如avl樹,但是這種嚴格平衡的樹,維護高度差需要設計復雜的算法去實現,時間成本也會增加,后來又有大牛提出,我們不讓他嚴格平衡,高度差不要太大就行,雖然會損失一點查詢速度,但是樹的復雜性大大降低,查詢效率也能滿足要求就行,這種樹就叫做紅黑樹。
數據查詢的時間主要依賴於磁盤 I/O 的次數,如果我們采用二叉樹的形式,即使通過平衡二叉搜索樹進行了改進,樹的深度也是 O(log2n),當 n 比較大時,深度也是比較高的。
這個時候大牛又來了,那就該成多叉樹吧,多叉樹可以降低高度,這樣就可以減少磁盤IO次數了,給這種樹起個名字,就叫多叉平衡樹,Balance Tree。那究竟該是多少個叉呢,這個是根據內存頁大小計算出來的。
Balance Tree也就是B樹,B樹的節點是可以存儲數據的,這樣就會造成查詢效率不穩定的情況,有時候訪問到了非葉子節點就可以找到關鍵字,而有時需要訪問到葉子節點才能找到關鍵字。
這個時候就又提出了B+樹,B+樹非葉子節點只存儲索引不存數據,葉子節點才存儲數據記錄,葉子節點又構成一個雙向鏈表並且從大到小順序鏈接。
歡迎大家去 我的博客 瞅瞅,里面有更多關於測試實戰的內容哦!!