B+樹在 MyISAM 和 InnoDB 的不同實現方式(圖)

1、MyISAM索引實現:

1)主鍵索引:

MyISAM引擎使用B+Tree作爲索引結構,葉節點的data域存放的是數據記錄的地址。

下圖是MyISAM主鍵索引的原理圖:
img

這裏假設表一共有三列,假設我們以Col1爲主鍵,上圖是一個MyISAM表的主索引(Primarykey)示意。可以看出MyISAM的索引文件僅僅保存數據記錄的地址。

2)輔助索引(Secondarykey)

在MyISAM中,主索引和輔助索引(Secondarykey)在結構上沒有任何區別,只是主索引要求key是唯一的,而輔助索引的key可以重複。

如果我們在Col2上建立一個輔助索引,則此索引的結構如下圖所示:

img

同樣也是一顆B+Tree,data域保存數據記錄的地址。因此,MyISAM中索引檢索的算法爲首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,則取出其data域的值,然後以data域的值爲地址,讀取相應數據記錄。

MyISAM的索引方式也叫做“非聚集”的,之所以這麼稱呼是爲了與InnoDB的聚集索引區分。

2、InnoDB索引實現

然InnoDB也使用B+Tree作爲索引結構,但具體實現方式卻與MyISAM截然不同。

1)主鍵索引:

MyISAM索引文件和數據文件是分離的,索引文件僅保存數據記錄的地址。而在InnoDB中,表數據文件本身就是按B+Tree組織的一個索引結構,這棵樹的葉節點 data 域 保存了完整的數據記錄。 這個索引的key是數據表的主鍵,因此InnoDB表數據文件本身就是主索引。

InnoDB主鍵索引的示意圖:
img

上圖所示,InnoDB主鍵索引的葉節點包含了完整的數據記錄(數據文件),這種索引叫做 聚集索引。

因爲InnoDB的數據文件本身要按主鍵聚集,所以InnoDB要求表必須有主鍵(MyISAM可以沒有),
如果沒有顯式指定,則MySQL系統會自動選擇一個可以唯一標識數據記錄的列作爲主鍵,
如果不存在這種列,則MySQL自動爲InnoDB表生成一個隱含字段作爲主鍵,這個字段長度爲6個字節,類型爲長整形。

2)InnoDB的輔助索引

InnoDB的所有輔助索引都引用主鍵作爲data域。 例如,下圖爲定義在Col3上的一個輔助索引:

img

InnoDB表是基於聚簇索引建立的。 因此InnoDB的索引能提供一種非常快速的主鍵查找性能。不過,它的輔助索引(SecondaryIndex,也就是非主鍵索引)也會包含主鍵列,所以,如果主鍵定義的比較大,其他索引也將很大。如果想在表上定義、很多索引,則爭取儘量把主鍵定義得小一些。InnoDB不會壓縮索引。

文字符的ASCII碼作爲比較準則。聚集索引這種實現方式使得按主鍵的搜索十分高效,但是輔助索引搜索需要檢索 兩遍索引 :首先 檢索輔助索引獲得主鍵,然後 用主鍵到主索引中檢索獲得記錄。

不同存儲引擎的索引實現方式對於正確使用和優化索引都非常有幫助。

例如,知道了InnoDB的索引實現後,就很容易明白爲什麼不建議使用過長的字段作爲主鍵,因爲所有輔助索引都引用主索引,過長的主索引會令輔助索引變得過大。

再例如,用非單調的字段作爲主鍵在InnoDB中不是個好主意,因爲InnoDB數據文件本身是一顆B+Tree,非單調的主鍵會造成在插入新記錄時數據文件爲了維持B+Tree的特性而頻繁的分裂調整,十分低效,而使用自增字段作爲主鍵則是一個很好的選擇。

3、總結,InnoDB索引和MyISAM索引的區別:

一是主索引的區別,InnoDB的數據文件本身就是索引文件。而MyISAM的索引和數據是分開的。

二是輔助索引的區別:InnoDB的輔助索引data域存儲相應記錄主鍵的值而不是地址。而MyISAM的輔助索引和主索引沒有多大區別。

4、擴展

普通二叉搜索樹當索引的劣勢:

(1)每個節點佔用的空間太少,不能很好的利用磁盤的預讀性。

(2)數據不規律的話,很可能形成鏈表。

(3)頻繁 IO。

B樹 當索引機制相比於二叉樹的優勢和劣勢:

(1)每個節點有關鍵字、數據區、子節點指針。

(2)每個節點存儲的數據多,可以充分的利用預讀性(mysql一個磁盤頁默認是16KB)。

B+樹 相比於B樹的優勢:

(1)因爲每個節點不存數據區(內存地址)了,所有每個節點的度可以更多,這樣樹的高度可以變矮很多,更利於查找。

(2)數據區都在葉子節點存着,一條鏈表,在排序時更有優勢。

(3)b+樹的節點變換時,是分裂形式而不是b樹的左旋轉(右旋轉)形式,效率高。

(4)但是B+樹有個缺點,就是不論查什麼數據都必須要遍歷到葉子節點纔可以拿到真實的數據地址。

MyISAM 和 InnoDB 的索引機制的不同:

(1)MyISAM 的索引和數據區是分成兩個文件來分別存儲的,InnoDB 的數據區是和主鍵索引放在一起的。

(2)MyISAM 的每個索引都是單獨的一棵樹,每個索引都存儲有真實的數據區地址,而 InnoDB 只有主鍵索引樹才存儲有真實地址,而輔助索引樹的葉子節點存儲的是主鍵的關鍵字。

(3)MyISAM 每個索引樹都可以獨當一面,而 InnoDB 的輔助索引樹就算找到了對應的關鍵字,也還是要到葉子節點拿到主鍵的關鍵字,然後再去主鍵索引樹遍歷。

(4)MyISAM 沒有默認的主鍵索引,而 InnoDB 有默認的主鍵索引(聚集索引)(不明確指定的情況下),InnoDB 除了主鍵索引是聚集索引,其他都是非聚集索引。

5、參考文章:

https://www.cnblogs.com/xyxxs/p/4440187.html

https://www.cnblogs.com/Booker808-java/p/10928509.html

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