myisam索引實現(xiàn)
myisam引擎使用b+tree作為索引結構,葉節(jié)點的data域存放的是數(shù)據(jù)記錄的地址。如圖:
這里設表一共有三列,假設我們以col1為主鍵,則上圖是一個myisam表的主索引(primary key)示意。可以看出myisam的索引文件僅僅保存數(shù)據(jù)記錄的地址。在myisam中,主索引和輔助索引(secondary key)在結構上沒有任何區(qū)別,只是主索引要求key是唯一的,而輔助索引的key可以重復。如果我們在col2上建立一個輔助索引,則此索引的結構如下圖所示:
同樣也是一顆b+tree,data域保存數(shù)據(jù)記錄的地址。因此,myisam中索引檢索的算法為首先按照b+tree搜索算法搜索索引,如果指定的key存在,則取出其data域的值,然后以data域的值為地址,讀取相應數(shù)據(jù)記錄。
myisam的索引方式也叫做“非聚集”的,之所以這么稱呼是為了與innodb的聚集索引區(qū)分。
innodb索引實現(xiàn)
雖然innodb也使用b+tree作為索引結構,但具體實現(xiàn)方式卻與myisam截然不同。
第一個重大區(qū)別是innodb的數(shù)據(jù)文件本身就是索引文件。從上文知道,myisam索引文件和數(shù)據(jù)文件是分離的,索引文件僅保存數(shù)據(jù)記錄的地址。而在innodb中,表數(shù)據(jù)文件本身就是按b+tree組織的一個索引結構,這棵樹的葉節(jié)點data域保存了完整的數(shù)據(jù)記錄。這個索引的key是數(shù)據(jù)表的主鍵,因此innodb表數(shù)據(jù)文件本身就是主索引。
上圖是innodb主索引(同時也是數(shù)據(jù)文件)的示意圖,可以看到葉節(jié)點包含了完整的數(shù)據(jù)記錄。這種索引叫做聚集索引。因為innodb的數(shù)據(jù)文件本身要按主鍵聚集,所以innodb要求表必須有主鍵(myisam可以沒有),如果沒有顯式指定,則mysql系統(tǒng)會自動選擇一個可以唯一標識數(shù)據(jù)記錄的列作為主鍵,如果不存在這種列,則mysql自動為innodb表生成一個隱含字段作為主鍵,這個字段長度為6個字節(jié),類型為長整形。
第二個與myisam索引的不同是innodb的輔助索引data域存儲相應記錄主鍵的值而不是地址。換句話說,innodb的所有輔助索引都引用主鍵作為data域。例如,下圖為定義在col3上的一個輔助索引:
這里以英文字符的ascii碼作為比較準則。聚集索引這種實現(xiàn)方式使得按主鍵的搜索十分高效,但是輔助索引搜索需要檢索兩遍索引:首先檢索輔助索引獲得主鍵,然后用主鍵到主索引中檢索獲得記錄。
總結
在數(shù)據(jù)庫開發(fā)中,了解不同存儲引擎的索引實現(xiàn)方式對于正確使用和優(yōu)化索引都非常有幫助。例如,知道了innodb的索引實現(xiàn)后,就很容易明白為什么不建議使用過長的字段作為主鍵,因為所有輔助索引都引用主索引,過長的主索引會令輔助索引變得過大。再例如,用非單調(diào)的字段作為主鍵在innodb中不是個好做法,因為innodb數(shù)據(jù)文件本身是一顆b+tree,非單調(diào)的主鍵會造成在插入新記錄時數(shù)據(jù)文件為了維持b+tree的特性而頻繁的分裂調(diào)整,十分低效,而使用自增字段作為主鍵則是一個很好的選擇。
到此這篇關于myisam與innodb索引實現(xiàn)對比的文章就介紹到這了,更多相關myisam與innodb索引對比內(nèi)容請搜索服務器之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://blog.csdn.net/z702143700/article/details/46049101