强烈建议看了第一个参考文献再来看这个篇博文,因为此处不准备讲底层数据结构的实现。

   索引:索引(Index)是帮助MySQL高效获取数据的数据结构。提取句子主干,就可以得到索引的本质:索引是数据结构。其表达的是存储引擎的范畴,也就是说只有在存储引擎级别谈索引才有意义。MyISAM、InnoDB、Memory等。此处单纯就InnoDB存储引擎讨论。

  需要提前掌握B-TREE、B+TREE数据结构。注意B+树“扫库”的功能。

  在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法。这种数据结构,就是索引

1、主码索引:就是在主码基础上建立的索引。primary key。在InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引。又称主码索引,聚集主码。

  此处的主索引又分为有序主码索引(例如id自增),和不按序排列的索引(例如name-varchar类型),此时对填充因子影响特别大。 

主码索引示例图

2、聚集主码。为什么主码索引(主索引)又称为聚集主码。此处的聚集其实是指数据文件与索引聚集在叶子节点,而不是像MyISAM中叶子节点存储的是数据文件的地址。可以看到叶节点包含了完整的数据记录。这种索引叫做聚集索引。因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键 (MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为 InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。

  聚集索引:每个表至多一个聚集索引,术语“聚集”指实际的数据行和相关的键值都保存在一起。聚集索引不是一种单独的索引类型,而是一种存储数据方式。其具体细节依赖于实现方式,但是InnoDB的聚集索引实际上在同样的结构中保存了B-Tree索引和数据行。当表有聚集索引的时候,它的数据行实际保存在索引的叶子页中。每个表只能有一个聚集索引,因为不能一次把行保存在两个地方。(但是,覆盖索引可以模拟多个聚集索引)。

当前,SolidDB和InnoDB是唯一支持聚集索引的存储引擎。InnoDB按照主键进行聚集,如果没有定义主键,InnoDB会试着使用唯一的非空索引来代替。如果没有这种索引,InnoDB就会定义隐藏的主键然后在上面进行聚集。

3、辅助索引。辅助索引是相对于主码索引而言的。在MyISAM中,辅助索引的结构和主码索引的结构是一样的,都是采用的是B+树结构,且叶子节点存储的都是数据记录的地址。而InnoDB中虽然也采用的是B+树存储,但是辅助索引的叶子节点存储的是对应于主码索引的主键。也就是说如果你通过辅助索引查找数据,要先在B+树中查找到主键,然后根据主索引查找到对应的记录,查找两次

4、非主码索引。又称非主索引和辅助索引,同上面辅助索引。

  注:要求主码列数据长度不能太长,因为辅助索引中叶子节点存储主键值,太长会导致辅助索引的额外存储空间太大。

  

5、唯一索引。唯一索引就是指列的值唯一,建立起来的索引,数据完整性检查。主索引肯定是唯一索引。一张表中可以有多个唯一索引,并且可以为NULL的列也可以建立唯一索引(NULL!=NULL),但是一张表中只能有一个主索引(主键唯一),并且该列不能为NULL,如果定义了AUTO INCREMENT列,该列必须是主索引的一部分。

6、外键索引。外键索引其实就是主索引或者辅助索引,主要用于表之间的连接操作等与外键有关的操作。如果为某个外键字段定义了一个外键约束条件,MySQL就会定义一个内部索引来帮助自己以最有效率的方式去管理和使用外键约束条件。目前MySQL默认的存储引擎中,只有InnoDB支持外键约束且不要求存在对应列的索引,但是通常考虑效率都应加上。

7、全文索引。文本字段上的普通索引只能加快对出现在字段内容最前面的字符串(也就是字段内容开头的字符)进行检索操作。如果字段里存放的是由几个、甚至是多个单词构成的较大段文字,普通索引就没什么作用了。这种检索往往以LIKE %word%的形式出现,这对MySQL来说很复杂,如果需要处理的数据量很大,响应时间就会很长。这类场合正是全文索引(full-text index)可以大显身手的地方。在生成这种类型的索引时,MySQL将把在文本中出现的所有单词创建为一份清单,查询操作将根据这份清单去检索有关的数 据记录。全文索引即可以随数据表一同创建,也可以等日后有必要时再使用下面这条命令添加:
ALTER TABLE tablename ADD FULLTEXT(column1, column2)
有了全文索引,就可以用SELECT查询命令去检索那些包含着一个或多个给定单词的数据记录了。下面是这类查询命令的基本语法:
SELECT * FROM tablename
WHERE MATCH(column1, column2) AGAINST(‘word1′, ‘word2′, ‘word3′)
上面这条命令将把column1和column2字段里有word1、word2和word3的数据记录全部查询出来。
注解:InnoDB数据表5.6之前不支持全文索引。

8、复合索引。又称混合索引或连接索引。符合索引其实就是多列索引。就是在几个列的基础上建立索引,其中复合索引的第一个列可以充当单列索引使用order by、group by等。当使用复合索引的时候,交换列的顺序可能会创建更好的索引。

9、覆盖索引。指满足了查询中给定表用到的所有的列。where子句、order by、group by以及select语句中的所有的列,全覆盖。

  覆盖索引适合那些很多主码较小长度和外键约束的大型规范化约束来说是理想的优化方式。因为InnoDB数据库中主码的值会被附加在非主码索引的每个对应的叶子节点的后面。

10、单列索引。是个统称。上述的主码索引、唯一键索引、外键索引、聚集主码、聚集索引、主索引等等,除了多列索引和聚合索引其他都属于单列索引。

11、普通索引。就是不是主索引、唯一索引等的索引。

参考文献:

  1、MySQL索引背后的数据结构及算法原理

  2、mysql索引的类型和优缺点

  3、[转]mysql索引结构原理、性能分析与优化

  4、mysql索引之聚集索引

版权声明:本文为xiangyangzhu原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/xiangyangzhu/p/index.html