MyISAM索引實現(xiàn)
MyISAM引擎使用B+Tree作為索引結(jié)構(gòu)佛玄,葉節(jié)點的data域存放的是數(shù)據(jù)記錄的地址。如圖:
這里設(shè)表一共有三列累澡,假設(shè)我們以Col1為主鍵梦抢,則上圖是一個MyISAM表的主索引(Primary key)示意±⒂矗可以看出MyISAM的索引文件僅僅保存數(shù)據(jù)記錄的地址奥吩。在MyISAM中,主索引和輔助索引(Secondary key)在結(jié)構(gòu)上沒有任何區(qū)別蕊梧,只是主索引要求key是唯一的霞赫,而輔助索引的key可以重復(fù)。如果我們在Col2上建立一個輔助索引肥矢,則此索引的結(jié)構(gòu)如下圖所示:
同樣也是一顆B+Tree端衰,data域保存數(shù)據(jù)記錄的地址。因此甘改,MyISAM中索引檢索的算法為首先按照B+Tree搜索算法搜索索引旅东,如果指定的Key存在,則取出其data域的值十艾,然后以data域的值為地址抵代,讀取相應(yīng)數(shù)據(jù)記錄。
MyISAM的索引方式也叫做“非聚集”的忘嫉,之所以這么稱呼是為了與InnoDB的聚集索引區(qū)分荤牍。
InnoDB索引實現(xiàn)
雖然InnoDB也使用B+Tree作為索引結(jié)構(gòu),但具體實現(xiàn)方式卻與MyISAM截然不同庆冕。
第一個重大區(qū)別是InnoDB的數(shù)據(jù)文件本身就是索引文件康吵。從上文知道,MyISAM索引文件和數(shù)據(jù)文件是分離的访递,索引文件僅保存數(shù)據(jù)記錄的地址晦嵌。而在InnoDB中,表數(shù)據(jù)文件本身就是按B+Tree組織的一個索引結(jié)構(gòu),這棵樹的葉節(jié)點data域保存了完整的數(shù)據(jù)記錄耍铜。這個索引的key是數(shù)據(jù)表的主鍵,因此InnoDB表數(shù)據(jù)文件本身就是主索引跌前。
上圖是InnoDB主索引(同時也是數(shù)據(jù)文件)的示意圖棕兼,可以看到葉節(jié)點包含了完整的數(shù)據(jù)記錄。這種索引叫做聚集索引抵乓。因為InnoDB的數(shù)據(jù)文件本身要按主鍵聚集伴挚,所以InnoDB要求表必須有主鍵(MyISAM可以沒有),如果沒有顯式指定灾炭,則MySQL系統(tǒng)會自動選擇一個可以唯一標(biāo)識數(shù)據(jù)記錄的列作為主鍵茎芋,如果不存在這種列,則MySQL自動為InnoDB表生成一個隱含字段作為主鍵蜈出,這個字段長度為6個字節(jié)田弥,類型為長整形。
第二個與MyISAM索引的不同是InnoDB的輔助索引data域存儲相應(yīng)記錄主鍵的值而不是地址铡原。換句話說偷厦,InnoDB的所有輔助索引都引用主鍵作為data域。例如燕刻,下圖為定義在Col3上的一個輔助索引:
這里以英文字符的ASCII碼作為比較準(zhǔn)則只泼。聚集索引這種實現(xiàn)方式使得按主鍵的搜索十分高效,但是輔助索引搜索需要檢索兩遍索引:首先檢索輔助索引獲得主鍵卵洗,然后用主鍵到主索引中檢索獲得記錄请唱。
總結(jié)
在數(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)整库说,十分低效狂鞋,而使用自增字段作為主鍵則是一個很好的選擇。
轉(zhuǎn)載整理潜的,如有不足骚揍,見諒。