由于MySQL中支持多种存储引擎,在不同的存储引擎中实现略微有所差距,下文中如果没有特殊声明,默认指的都是InnoDB存储引擎。
索引从不同维度划分可以有很多种名称,但是需要明确一个问题——索引的本质是一种数据结构,其他索引的划分则是针对实际应用而言。
索引是提高查询效率的数据结构,而能够提高查询效率的数据结构有很多,如二叉搜索树,红黑树,跳表,哈希表(散列表)等,而MySQL中用到了B+Tree和散列表(Hash表)作为索引的底层数据结构(其实也用到了跳表实现全文索引,但这不是重要考点,所以可以忽略)。
1. hash索引MySQL并没有显式支持Hash索引,而是作为内部的一种优化。具体在Innodb存储引擎里,会监控对表上二级索引的查找,如果发现某二级索引被频繁访问,二级索引成为热数据,就为之建立hash索引。因此,在MySQL的Innodb里,对于热点的数据会自动生成Hash索引。这种hash索引,根据其使用的场景特点,也叫自适应Hash索引。2. B+树索引这个是MySQL索引的基本实现方式。除了全文索引、hash索引,Innodb、MyISAM的索引都是通过B+树实现的。为了能应对不同的数据检索需求,索引既可以仅包含一个字段,也可以同时包含多个字段。单个字段组成的索引可以称为单值索引,否则称之为复合索引,也称为组合索引或多值索引。
这个很好理解,假如我们有一张表,有三个属性,分别是 id,age 和 name 。假如在id上建立索引,那这就是单值索引;如果在 name 和 age 上建立索引,那这就是复合索引。
复合索引的索引的数据顺序跟字段的顺序相关,包含多个值的索引中,如果当前面字段的值重复时,将会按照其后面的值进行排序。
使用覆盖索引的前提是字段长度比较短,对于值长度较长的字段则不适合使用覆盖索引,原因有很多,比如索引一般存储在内存中,如果占用空间较大,则可能会从磁盘中加载,影响性能。
根据数据与索引的存储关联性,可以分为聚簇索引和非聚簇索引(也叫聚集索引和非聚集索引)。聚簇索引也叫簇类索引,是一种对磁盘上实际数据重新组织以按指定的一个或多个列的值排序。整个简洁的说法,这俩的区别就是索引的存储顺序和数据的存储顺序是否是关系的,有关就是聚簇索引,无关就是非聚簇索引。具体实现方式根据索引的数据结构不同会有所不同。下面以B+树实现的索引为例,举例来说明聚簇索引和非聚簇索引。
1. 聚簇索引Innodb的主键索引,非叶子节点存储的是索引指针,叶子节点存储的是既有索引也有数据,是典型的聚簇索引(这里可以发现,索引和数据的存储顺序是强相关的。因此是典型的聚簇索引),如图:2. 非聚簇索引MyISAM中索引和数据文件分开存储,B+Tree的叶子节点存储的是数据存放的地址,而不是具体的数据,是典型的非聚簇索引;换言之,数据可以在磁盘上随便找地方存,索引也可以在磁盘上随便找地方存,只要叶子节点记录对了数据存放地址就行。因此,索引存储顺序和数据存储关系毫无关联,是典型的非聚簇索引,另外Inndob里的辅助索引也是非聚簇索引。