知方号

知方号

mysql聚簇索引(聚集索引)和非聚簇索引(二级索引、辅助索引)的区别

mysql聚簇索引(聚集索引)和非聚簇索引(二级索引、辅助索引)的区别

文章目录 总结1. 聚簇索引一个坑 2. 非聚簇索引3. 二级索引

总结

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

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

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

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

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

在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中的二级索引》

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至lizi9903@foxmail.com举报,一经查实,本站将立刻删除。