Mysql之B樹索引

聚集索引: 
簡單概念:一個表中根據主鍵創建的一棵B+樹,索引的葉子節點存放了表中所有的記錄,存儲記錄在物理位置上是連續的,一個葉子節點存放一條對應的記錄(PS:是根據主鍵創建的B+樹,葉子節點存數據記錄) 。
舉個例子(以漢語字典爲例): 
漢語字典的正文本身就是一個聚集索引,比如我們要查“安”字,由於漢語詞典的拼音排序是從“a”開始到“z”結尾的,則“安”字自然而然就排在字典前部,若翻遍了所有以“a”開頭的部分仍找不到該字,
則說明“安”不在字典中;同理,若想查“張”字,我們會將字典翻到最後一部分,因爲拼音是“zhang”。而在我們的這些查找中,我們僅僅依靠正文就可以進行相應的查找;也就是說,字典的正文部分本身就是一個目錄,我們不需要再通過其他目錄的查找來找到我們需要的內容。
正文內容本身就是按照一定規則排列的目錄便稱爲“聚集索引”。每個表只能有一個聚集索引,因爲目錄只能按照一種方法進行排列,且每個表的主鍵是唯一的 。
非聚集索引:
簡單概念:非聚集索引是根據索引字段創建的一棵B+樹,索引的葉子節點僅存放索引鍵值以及該鍵值指向的主鍵,存儲記錄在邏輯上是連續的(PS:根據索引字段創建的B+樹,葉子節點只存放索引鍵值與記錄的主鍵) 
舉個例子(還是以漢語字典爲例): 
當我們遇到不認識的字且不知道它的發音,這時候,我們就不能按照前面的方法找到要查的字,而是需要根據“偏旁部首”查找要找的字,然後根據這個字後的頁碼直接翻到某頁來找到要找的字,但我們結合“部首目錄”和“檢字表”而查到的字的排序並不是真正的正文的排序方法,
比如我們查“張”字,在查部首之後的檢字表中“張”的頁碼是672頁,檢字表中“張”的上面是“弛”字,但頁面卻是63頁,“張”的下面是“弩”字,頁面是390頁,很顯然,
這些字在正文中並不是真正的分別處於“張”字的上下方,現在看到的連續的“弛,張,弩”三字的順序實際上就是它們在非聚集索引中的排序,是字典正文中的字在非聚集索引中的映射,我們可以通過這種方式來找到所需要的字,但這包含2個過程,
先找到目錄中的結果,再根據找到的結果來翻到我們所需要的頁面,這種目錄純粹是目錄,正文純粹是正文的排序方式就是“非聚集索引” 。
聚集索引與非聚集索引的主要區別: 
a.存儲特點的區別: 
聚集索引按索引順序來存儲,索引項順序與表中記錄的物理順序一致,葉子節點即存儲了真實數據行,不再有另外的單獨數據頁,一張表上最多隻有一個聚集索引; 
非聚集索引表的存儲順序與索引順序無關,僅僅索引項的邏輯上是連續的,葉子節點存儲了索引字段值以及指向數據頁數據行的邏輯指針,其行數量與數據錶行數據量一致。 

b.更新表數據的區別: 
插入數據:無聚集索引的表,表中數據行沒特定順序,新行皆被添加到表的末尾;有聚集索引的表,先根據索引找到對應的數據頁,挪動已有記錄爲新數據騰出空間後插入,若數據頁已滿,則拆分數據頁,調整索引指針(若表中有非聚集索引,則更新索引指向新的數據頁); 
刪除數據:無聚集索引的表,直接刪除(留下內存空洞);有聚集索引的表,刪除行將導致其下的數據行向上移動以填補空白,若刪除的行爲數據頁最後一行,則回收該數據頁,相應索引頁中記錄也被刪除。 
InnoDB的B+樹索引: 
a.InnoDB是索引組織表的,即數據文件本身就是按照B+樹方式存放數據的; 
b.InnoDB引擎中可以有聚集索引與非聚集索引,這2種索引每個頁大小都爲16k,且不能更改; 
c.由於非聚集索引不包含行記錄所有數據,因此每頁可以存放比聚集索引更多的鍵值,高度一般都小於聚集索引; 
d.若在InnoDB表建立時沒顯式指定主鍵,則InnoDB會自動創建一個6字節的列作爲主鍵; 
e.InnoDB中,主鍵的值會附加在每個非主鍵索引(非聚集索引)對應記錄後面,無需重複添加到覆蓋索引列中,這也是爲什麼我們常說InnoDB主鍵長度越小越好; 
f.若非聚集索引是包含主鍵的聯合索引,也不需要一個額外的列存放主鍵值,它會通過聯合索引中的主鍵進行查找。 
小圖一張,展示下InnoDB中聚集索引與非聚集索引的關係 。

MyISAM 的B+樹索引: 
a.MyISAM是堆組織表,沒有聚集索引的概念; 
b.MyISAM表所有的行數據都存放在MYD文件中,B+樹索引都存放在MYI文件中,且都是非聚集索引; 
c.主鍵索引與其他索引不同之處在於必須是唯一的,且不可爲null,索引頁大小爲1k,且不可調整; 
d.由於沒有聚集索引,故其索引葉節點存放的鍵值不是主鍵值,而是對應記錄在MYD文件中的物理位置; 
這也是爲什麼MyISAM表記錄刪除之後數據文件大小沒什麼變化,留下內存碎片,造成“空洞”的現象(可用 “OPTIMIZE TABLE 表名” 進行定期清理,會鎖表)。 
小圖一張,展示下MyISAM中MYD與MYI的關係 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章