【mysql】聚簇索引(聚集索引)和非聚簇索引(二级索引、辅助索引)的区别
在《数据库原理》一书中是这么解释聚簇索引和非聚簇索引的区别的:聚簇索引的叶子节点就是数据节点,而非聚簇索引的叶子节点仍然是索引节点,只不过有指向对应数据块的指针。在mysql数据库中,myisam引擎和innodb引擎使用的索引类型不同,myisam对应的是非聚簇索引,而innodb对应的是聚簇索引。聚簇索引也叫复合索引、聚集索引等等。聚簇索引:“聚簇”的意思是数据行被按照一定顺序一个个紧密地排列
总结
聚簇索引也叫聚集索引
。,并不是一种单独的索引类型,而是一种数据存储方式。那么可以理解聚簇索引是一种抽象概念,在具体实现的时候,需要区分不同的引擎
,不同的引擎,实现细节有所不同。
不同的引擎有不同的实现, 很多文章忽略了区分引擎,因此让人很迷惑。
那么什么是聚簇索引?
聚簇索引的叶子节点就是数据节点,也就是说索引和数据行在一起;反之,如果叶子节点没有存储数据行,那么就是非聚簇索引。
二级索引,又称作辅助索引,均属于非聚簇索引
如果反过来说,非聚簇索引就是二级索引,这种说法完全就是错误的。就像学生是人,但是人是学生就不对。
在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中的二级索引》
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)