【MySQL】InnoDB存储引擎,MyISAM存储引擎,聚集索引,非聚集索引,主键索引,二级索引他们之间的关系梳理
目录
在最初学习MySQL底层原理的时候,对InnoDB和MyISAM存储引擎对聚集索引和非聚集索引的实现结构,主键索引和二级索引的概念都很混乱,网上的很多博客在一些概念上的表述也都不尽相同,现在我对之前比较混乱的概念做一个总结梳理。
聚集索引并不是一种索引类型,而是一种数据存储方式。至于如何实现聚集索引定义的数据存储方式,不同的存储引擎会有自己不同的实现,所以下面我们就用最主流的InnoDB引擎和MyISAM引擎来做详细的讲解。
1、主键索引和二级索引
首先定义一下什么叫主键索引,什么叫二级索引。主键索引一个表中只能有一个,也就是说除了主键索引以外的索引类型,都是二级索引。二级索引也叫辅助键索引。注意二级索引(辅助键索引)并不是一个具体的索引类型,而是很多种索引的统称。
2、InnoDB存储引擎
InnoDB存储引擎支持聚集索引,但这并不意味着InnoDB表中的所有索引都是聚集索引。InnoDB表中有聚集索引,也有非聚集索引。
InnoDB对聚集索引的实现是通过直接将表数据按照索引的顺序一一存储在叶子节点当中。这也就保证了数据在物理存储器中的真实存储顺序和逻辑上的索引顺序是一致的。而因为在真实的物理存储器中同一个数据只能由一个物理地址,所以聚集索引在同一个表中只能有一个。
所有的索引类型中,除了聚集索引之外的索引都是非聚集索引。在InnoDB存储引擎中,将主键索引用聚集索引来管理,相应的其他的索引类型,也就是二级索引,就是非聚集索引。InnoDB中的二级索引是通过在叶子节点中存放相对应的主键值来管理的。
2.1 总结:
InnoDB存储引擎支持聚集索引,也支持非聚集索引。该引擎将主键索引用聚集索引的方式来管理,因为聚集索引在一个表中只能有一个,所以其他的索引类型都是非聚集索引,所以InnoDB的二级索引就是通过非聚集索引来管理的。
3、MyISAM存储引擎
MyISAM引擎不支持聚集索引,MyISAM表中的索引都是非聚集索引。MyISAM存储引擎是通过在叶子节点中存储指向真实行数据的指针来实现非聚集索引的。因为MyISAM引擎不支持聚集索引,所以他的所有索引类型都是非聚集索引,这其中就包括主键索引和二级索引。
因为都是非聚集索引,所以在MyISAM引擎中主键索引和二级索引基本没有什么区别,只有节点中的索引字段不同罢了,它们的叶子节点都是存储的指向数据行存储位置的指针。从这里就可以看出非聚集索引中的数据行数据在物理存储器中的真实位置和索引的逻辑顺序是不同的。
3.1 总结:
InnoDB存储引擎中,主键索引就可以特指聚集索引,二级索引就可以特指非聚集索引,因为该引擎就规定了主键索引用聚集索引来管理,而聚集索引在一个表中只能有一个,所以其他的索引类型就都是非聚集索引
MyISAM存储引擎中,因为它不支持聚集索引,所以该引擎中的所有索引类型都是非聚集索引,即在MyISAM存储引擎中主键索引和二级索引都是非聚集索引。
4、不同存储引擎对聚集索引和非聚集索引的实现方式不同
上面也说了聚集索引和非聚集索引只是规定了一种数据存储的方式,至于如何实现这个方式,不同的存储引擎是不同的。就比如说在InnoDB存储引擎中的非聚集索引,也就是那些二级索引的叶子节点是存储的主键的值。而MyISAM存储引擎中的非聚集索引的叶子节点就都是存储的指向对应数据行在物理存储器中的位置。
5、二次查询问题
只有InnoDB存储引擎中的非聚集索引才有二次查询问题,InnoDB的主键索引,因为它是通过聚集索引的方式管理的,所有表数据都存在叶子节点,所以没有二次查询问题。MyISAM存储引擎只支持非聚集索引,它的非聚集索引的实现方式是是叶子节点中存储指向数据行的指针,可以直接取得全部的数据行数据,所以MyISAM表中的主键索引和二级索引都没有二次查询问题。
InnoDB的聚集索引不存在二次查询问题,因为数据就在自己的叶子节点中存着,不需要再额外进行二次查询。而上面也说了,只有InnoDB存储引擎的非聚集索引才会有二次查询问题,MyISAM存储引擎的非聚集索引没有二次查询问题,这是因为非聚集索引的二次查询问题在InnoDB存储引擎和MyISAM存储引擎中是不太一样的,不同的存储引擎对聚集索引和非聚集索引的实现方式是不同的。InnoDB中的非聚集索引(二级索引)是在叶子节点中存储的是主键值,所以InnoDB中在二级索引树中取得叶子节点之后如果索引字段没有覆盖查询字段,就需要进行一次回表,再利用得到的主键值去搜索主键索引树,这就是二次查询。而MyISAM引擎不会出现二次搜索的问题,原因在上一段已经写了。
其他相关文章:【MySQL】Mysql的存储引擎和索引详解(聚集索引和非聚集索引)
【MySQL】InnoDB行格式、数据页结构以及索引底层原理分析