我的歸納:
(1)InnoDB的主鍵采用聚簇索引存儲,使用的是B+Tree作為索引結構,但是葉子節點存儲的是索引值和數據本身(注意和MyISAM的不同)。
(2)InnoDB的二級索引不使用聚蔟索引,葉子節點存儲的是KEY字段加主鍵值。因此,通過二級索引查詢首先查到是主鍵值,然后InnoDB再根據查到的主鍵值通過主鍵索引找到相應的數據塊。
(3)MyISAM的主鍵索引和二級索引葉子節點存放的都是列值與行號的組合,葉子節點中保存的是數據的物理地址
(4)MyISAM引擎使用B+Tree作為索引結構,葉節點的data域存放的是數據記錄的地址
(5)為什么用B+Tree 不是BTree:
B-Tree:如果一次檢索需要訪問4個節點,數據庫系統設計者利用磁盤預讀原理,把節點的大小設計為一個頁,那讀取一個節點只需要一次I/O操作,完成這次檢索操作,最多需要3次I/O(根節點常駐內存)。數據記錄越小,每個節點存放的數據就越多,樹的高度也就越小,I/O操作就少了,檢索效率也就上去了。
B+Tree:非葉子節點只存key,大大滴減少了非葉子節點的大小,那么每個節點就可以存放更多的記錄,樹更矮了,I/O操作更少了。所以B+Tree擁有更好的性能。
下面是原文中對聚簇索引的介紹,介紹的很簡單易懂:
1.聚簇索引是對磁盤上實際數據重新組織以按指定的一個或多個列的值排序的算法。特點是存儲數據的順序和索引順序一致。
一般情況下主鍵會默認創建聚簇索引,且一張表只允許存在一個聚簇索引。
在《數據庫原理》一書中是這么解釋聚簇索引和非聚簇索引的區別的:
聚簇索引的葉子節點就是數據節點,而非聚簇索引的葉子節點仍然是索引節點,只不過有指向對應數據塊的指針。
因此,MySQL中不同的數據存儲引擎對聚簇索引的支持不同就很好解釋了。
2.下面,我們可以看一下mysql中MYISAM和INNODB兩種引擎的索引結構。
如原始數據為:
MyISAM引擎的數據存儲方式如圖:
(1)MYISAM是按列值與行號來組織索引的。它的葉子節點中保存的實際上是指向存放數據的物理塊的指針。
從MYISAM存儲的物理文件我們能看出,MYISAM引擎的索引文件(.MYI)和數據文件(.MYD)是相互獨立的。
(2)而InnoDB按聚簇索引的形式存儲數據,所以它的數據布局有着很大的不同。它存儲數據的結構大致如下:
注:聚簇索引中的每個葉子節點包含主鍵值、事務ID、回滾指針(rollback pointer用於事務和MVCC)和余下的列(如col2)。
(3)INNODB的二級索引與主鍵索引有很大的不同。InnoDB的二級索引的葉子包含主鍵值,而不是行指針(row pointers),這減小了移動數據或者數據頁面分裂時維護二級索引的開銷,因為InnoDB不需要更新索引的行指針。其結構大致如下:
INNODB和MYISAM的主鍵索引與二級索引的對比:
(4)InnoDB的的二級索引的葉子節點存放的是KEY字段加主鍵值。因此,通過二級索引查詢首先查到是主鍵值,然后InnoDB再根據查到的主鍵值通過主鍵索引找到相應的數據塊。而MyISAM的二級索引葉子節點存放的還是列值與行號的組合,葉子節點中保存的是數據的物理地址。所以可以看出MYISAM的主鍵索引和二級索引沒有任何區別,主鍵索引僅僅只是一個叫做PRIMARY的唯一、非空的索引,且MYISAM引擎中可以不設主鍵。