总结

聚簇索引也叫聚集索引。,并不是一种单独的索引类型,而是一种数据存储方式。那么可以理解聚簇索引是一种抽象概念,在具体实现的时候,需要区分不同的引擎,不同的引擎,实现细节有所不同。

不同的引擎有不同的实现, 很多文章忽略了区分引擎,因此让人很迷惑。

那么什么是聚簇索引?
聚簇索引的叶子节点就是数据节点,也就是说索引和数据行在一起;反之,如果叶子节点没有存储数据行,那么就是非聚簇索引。

二级索引,又称作辅助索引,均属于非聚簇索引

如果反过来说,非聚簇索引就是二级索引,这种说法完全就是错误的。就像学生是人,但是人是学生就不对。

在mysql数据库中,myisam引擎和innodb引擎使用的索引类型不同,myisam对应的是非聚簇索引,而innodb对应的是聚簇索引

1. 聚簇索引

《高性能MySQL》上说聚簇索引并不是一种单独的索引类型,而是一种数据存储方式。那么mysql有哪些索引类型呢,参见《Mysql目前主要的几种索引类型》

例如,某个冒泡排序算法,对应这里的存储方式,是排序的算法的一种概念,你可以用java写出这个算法,也可以用c写出这个算法,具体语言,对应这里的索引类型。

聚簇索引的叶子节点就是数据节点,也就是说索引和数据行在一起。

那么采用聚簇索引架构的innodb来说,他的叶子节点和数据行就是在一起的。我们来看下innodb B+树的实现:
在这里插入图片描述
一个表只能有一个聚簇索引。

我们知道聚簇索引中包含了数据行,那么如果有多个聚簇索引,就说明存储了多份相同的数据行,岂不浪费空间?

联想innodb的存储文件,在一个数据table中,它的数据文件和索引文件是同一个文件。即在查询过程中,找到了索引,便找到了数据文件。这也间接说明innodb采用的是聚簇索引。

聚簇索引默认由主键实现(用主键作为B+树的key,并且把数据行绑定在叶子节点)。

如果表中没有定义主键A,InnoDB 会选择一个唯一且非空的列B代替(主键A的特性就是唯一且非空,如果把主键A比作嫡长子,那么列B就是其他儿子,只是继承的顺序靠后,但毕竟也是有皇家血脉的,没有嫡长子,就拿其他儿子当继承人了)。

如果没有这样的列B,InnoDB 会隐式定义一个主键(类似oracle中的RowId)来作为聚簇索引。

如果已经设置了主键为聚簇索引又希望再单独设置聚簇索引,必须先删除主键,然后添加我们想要的聚簇索引,最后恢复设置主键即可。

一个坑

在一篇文章中有如下介绍,说法是不准确的:

“在《数据库原理》一书中是这么解释聚簇索引和非聚簇索引的区别的:聚簇索引的叶子节点就是数据节点,而非聚簇索引的叶子节点仍然是索引节点,只不过有指向对应数据块的指针

我们知道聚簇索引是一个概念,那么非聚簇索引自然也是一个概念,需要明确指出的是InnoDB和myisam均用到非聚簇索引,但是他们有不同的实现。

因此上面引用的话中,对非聚簇索引的描述”只不过有指向对应数据块的指针”,特指myisam的非聚簇索引实现,而对于innodb的非聚簇索引实现,data指向的是主键值(通过主键值,去聚簇索引进行索引操作,找到叶子节点,数据在该叶子节点上,这个过程好像叫回表),不是数据行,也不是指针。

当初没明白这些道理时,被搞的要吐血了

2. 非聚簇索引

由前文知道,myisam采用非聚簇索引实现,那么我们来看下具体是怎么实现的。

在myisam中,一个数据表table的存储文件,它是由table.frm、table.myd以及table.myi组成。table.myd记录了数据(数据行),table.myi记录了索引的数据。

myisam引擎的索引文件和数据文件是独立分开的,正好符合非聚簇索引的架构。

MyISM使用的是非聚簇索引,非聚簇索引和InnoDB的聚簇索引这两棵B+树看上去没什么不同,节点的结构完全一致,只是存储的内容不同而已,InnoDB主键聚簇索引B+树的节点存储了主键和数据行,MyISM非聚簇索引B+树存储了主键和指向data的指针

在这里插入图片描述

3. 二级索引

二级索引,又被称为辅助索引,在不同存储引擎中的内容不同。

InnoDB中的二级索引存放的是主键值,如果需要查询对应的数据行,需要回表查询,即在聚簇索引中进一步查找对应的数据行。这样可以避免在行移动或者插入新数据时出现的页分裂问题。

InnoDB的二级索引更详细信息,可以参见《InnoDB二级索引(辅助索引)》

MyISAM无论是主键索引还是二级索引索引的叶子节点存放的都是指向数据行的指针,保证可以通过索引进而查找到对应的数据行,只需要对索引进行一遍查找。这样会存在页分裂问题。


参考:
《聚簇索引和非聚簇索引的区别》 开篇定义聚簇索引那句话

《Mysql聚簇索引和非聚簇索引》 参考主体,但“聚簇索引也叫复合索引”描述是错误的

《MySQL-聚簇索引》 《高性能MySQ》一书的笔记

《mysql聚簇索引详解》 好像也是《高性能MySQ》的笔记

《聚簇索引与非聚簇索引(也叫二级索引)》
《mysql——二级索引(辅助索引)》二级索引作用
《MySQL在Innodb和MyISAM中的二级索引》

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐