索引分类
注意,INNODB是MYsql的存储引擎,首先Mysql的索引分类仅仅是按照平时书写的sql命名的索引。INNODB的索引分类指的是按照不同的场景下的索引分类。
Mysql的索引
普通索引,唯一索引,主键索引
1. 普通索引
普通索引的唯一任务是加快对数据的访问速度,因此,应该只为那些最经常出现在查询条件(WHERE column=)或者排序条件(ORDERBY column)中的数据列创建索引。
2. 唯一索引
它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。用关键字UNIQUE把它定义为一个唯一索引。有新纪录插入数据表时,自动检查新纪录的这个字段的值是否已经在某个记录的这个字段里出现过了。如果是,mysql将拒绝插入那条新纪录
3. 主键索引
它是一种特殊的唯一索引,不允许有空值。一般是在建表的时候同时创建主键索引。与数据在磁盘上存储的物理结构有关系。
INNODB的索引
1)B+树索引 :聚集索引(主键索引)和非聚集索引(二级索引,辅助索引,联合索引,)
2)全文索引
3)哈希索引
根据INNODB和MYisAM存储数据和索引文件所在位置不同
1)聚簇索引
表数据和索引在磁盘上是一个文件存储,应用:MYSQL的INNIODB存储引擎
2)非聚簇索引
表数据和索引在磁盘上分开存储,应用:MYSQL的MYISAM存储引擎
具体索引分析
1. 聚集索引和主键索引
什么是聚集索引?
按照每个表的主键构造一颗B+树,同时叶子节点中存放的是存放整张表的行记录数据。说索引项的顺序与表中记录的物理顺序一致。对于聚集索引,叶子结点即存储了真实的数据行,不再有另外单独的数据页。 在一张表上最多只能创建一个聚集索引,因为真实数据的物理顺序只能有一种。
主键索引
如果没有显示在表中指定主键,InnoDB按照一定方式选择或者创建主键:
1)首先判断表中是否有非空的唯一索引,如果有,则该列为主键,当存在多个非空唯一索引时,主键选择第一个(这个顺序是定义索引的顺序)定义的非空唯一索引为主键。
2)如果不存在非空的唯一索引,INNODB会为每一行生成一个6字节的rowid(行id)作为主键。
2.非聚集索引、辅助索引、二级索引
1)叶子节点不包含行记录的全部数据,叶子节点包含一个书签,来指向相应行数据的聚集索引键。
2)由于辅助索引的存在并不影响聚集索引中的组织,所以可以存在多个辅助索引。
3)当通过辅助索引来查询数据时,Innodb存储引擎会遍历辅助索引并通过叶子级别的指针获取到指向主键索引的主键,然后再通过主键索引来找到一个完整的行记录。(但是并非必须是这个流程),这里牵扯一个回表的过程。
3.覆盖索引
是非聚集索引,但是可以直接从辅助索引中得到查询的记录,不需要在一次查询聚集索引中的记录。好处是辅助索引不包含行记录的所有信息。大小远小于聚集索引,因此可以减少IO操作。减少一个回表过程。
4.联合索引
联合索引是非聚集索引,联合索引也是一颗B+树,但是联合索引的键值数量大于等于2.如果是三个列建立索引,那么按照先a,b,再c的顺序排序。对表上多个列进行索引,满足最左前缀匹配的原则。
mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。
5.全文索引
比如like查询:以%为开头的查询,B+树索引失效。
全文索引:将存储在数据库中的整本书或者整篇文章中的任何内容信息查找出来。
倒排索引来实现,辅助表中存储了单词与单词自身在一个或者多个文档中所在位置的映射,通常利用关联数组来实现,InnoDB中的关联数组形式为 {单词,(单词所在文档的 ID,在具体文档中的位置),((单词所在文档的 ID,在具体文档中的位置)}
6.哈希索引
实现:使用哈希算法来对字典进行查找,其冲突机制采用链表方式。把索引字段映射成对应的哈希码然后再存放在对应的位置。由数据库自身创建并使用。
存在缺陷:
1、不支持模糊查找的话,只能遍历这个表。而B+树则可以通过最左前缀原则快速找到对应的数据。但是%要位于索引关键字后面,前面的话会采用全文检索的倒排索引。
2、不支持范围查找,只能遍历全表。
3、极端情况,很多索引的哈希码一致,那么将会退化成一个链表。查找时间复杂度增大。