MySQL - MySQL不同存储引擎下索引的实现
文章目錄
- 生猛干貨
- Pre
- MyISAM索引實現
- 非聚簇(非聚集)索引
- 索引原理圖
- InnoDB索引實現
- 聚簇(聚集)索引
- 索引原理圖
- 常見面試題
- 為什么建議InnoDB表必須建主鍵,并且推薦使用整型的自增主鍵?
- 為什么非主鍵索引結構葉子節點存儲的是主鍵值?(一致性和節省存儲空間)
- 搞定MySQL
生猛干貨
帶你搞定MySQL實戰,輕松對應海量業務處理及高并發需求,從容應對大場面試
Pre
MySQL中,索引屬于存儲引擎級別的概念,不同存儲引擎對索引的實現方式是不同的,我們這里主要討論MyISAM和InnoDB兩個存儲引擎的索引實現方式。
MyISAM索引實現
非聚簇(非聚集)索引
我們建立一個myIsam存儲引擎的表,看磁盤上的文件存儲如下
我這個是8.0的MYSQL, 5.7版本 不是sdi結尾的文件,而是frm (framework)
可以看到MyISAM存儲引擎的索引文件 MYI 和數據文件 MYD 是分離的(非聚集)
這就是非聚簇索引的含義, MYI 和 MYD 分開存儲 ,同樣的 InnoDB都存在.idb文件中,所以InnoDB存儲引擎的索引就是聚簇索引。
索引原理圖
MyISAM引擎使用B+Tree作為索引結構,葉節點的data域存放的是數據記錄的地址。
上圖就是 MyISAM索引的原理圖。
上圖一共有三列,假設我們以Col1為主鍵,則上圖是一個MyISAM表的主索引(Primary key)示意??梢钥闯?strong>MyISAM的索引文件僅僅保存數據記錄的地址
在MyISAM中,主索引和輔助索引(Secondary key)在結構上沒有任何區別,只是主索引要求key是唯一的,而輔助索引的key可以重復。
如果我們在Col2上建立一個輔助索引,則此索引的結構如下圖所示:
同樣也是一顆B+Tree,data域保存數據記錄的地址。
因此,MyISAM中索引檢索的算法為首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,則取出其data域的值,然后以data域的值為地址,去另外一個文件中MYD讀取相應數據記錄。
MyISAM的索引方式也叫做“非聚集”的,之所以這么稱呼是為了與InnoDB的聚集索引區分。
InnoDB索引實現
聚簇(聚集)索引
建立一個innodb存儲引擎的表,看磁盤上的數據文件如下
這個ibd就是 數據和索引,這兩個存儲在一個文件中
第一個重大區別是InnoDB的數據文件本身就是索引文件 ,因為就只有一個ibd文件啊。
-
MyISAM索引文件和數據文件是分離的,索引文件僅保存數據記錄的地址。
-
InnoDB中,表數據文件本身就是按B+Tree組織的一個索引結構,這棵樹的葉節點data域保存了完整的數據記錄。這個索引的key是數據表的主鍵,因此InnoDB表數據文件本身就是主索引。
InnoDB也使用B+Tree作為索引結構,但具體實現方式卻與MyISAM 不同。
索引原理圖
上圖就是InnoDB主索引(同時也是數據文件)的示意圖,可以看到葉節點包含了完整的數據記錄。這種索引叫做聚集索引。
第二個與MyISAM索引的不同是InnoDB的輔助索引data域存儲相應記錄主鍵的值而不是地址。換句話說,InnoDB的所有輔助索引都引用主鍵作為data域
上圖為 定義在Col3上的一個輔助索引 觀察葉子節點 : data域存儲相應記錄主鍵的值而不是地址
Col3字段上的索引,以英文字符的ASCII碼作為比較準則。
聚集索引這種實現方式使得按主鍵的搜索十分高效,但是輔助索引搜索需要檢索兩遍索引:首先檢索輔助索引獲得主鍵,然后用主鍵到主索引中檢索獲得記錄。
常見面試題
為什么建議InnoDB表必須建主鍵,并且推薦使用整型的自增主鍵?
因為InnoDB的數據文件本身要按主鍵聚集,所以InnoDB要求表必須有主鍵(MyISAM可以沒有),如果沒有顯式指定,則MySQL系統會自動選擇一個可以唯一標識數據記錄的列作為主鍵,如果不存在這種列,則MySQL自動為InnoDB表生成一個隱含字段作為主鍵,這個字段長度為6個字節,類型為長整形。
至于是整型,主要是構建B+Tree的時候,從左到右遞增的屬性,你如果用過UUID,不僅占用空間,還要轉換成assic碼進行比較,效率自然不行。
為什么非主鍵索引結構葉子節點存儲的是主鍵值?(一致性和節省存儲空間)
知道了InnoDB的索引實現后,就很容易明白為什么不建議使用過長的字段作為主鍵,因為所有輔助索引都引用主索引,過長的主索引會令輔助索引變得過大,占用空間。
再比如用非單調(可重復)的字段作為主鍵在InnoDB中是不推薦的,因為InnoDB數據文件本身是一顆B+Tree,可重復的主鍵會造成在插入新記錄時數據文件為了維持B+Tree的特性而頻繁的分裂調整,十分低效,所以推薦使用自增主鍵。
參考 : http://blog.codinglabs.org/articles/theory-of-mysql-index.html
搞定MySQL
總結
以上是生活随笔為你收集整理的MySQL - MySQL不同存储引擎下索引的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL - 剖析MySQL索引底层数
- 下一篇: MySQL - Explain深度剖析