Mysql必知必会之二级索引

二级索引

二级索引也被称为非聚簇索引,本身也就是一颗B+树,一个二级索引对应一颗B+树,但是二级索引B+树存储的数据跟聚簇索引不一样。聚簇索引前面也说了,叶子节点存的就是我们插入到数据库的数据,非叶子节点存的就是数据的主键id和对应的数据页号。而二级索引叶子节点存的是索引列的数据和对应的主键id,非叶子节点除了索引列的数据和id之外,还会存数据页的页号。

前面提到的数据页,其实真正是叫索引页,因为叶子节点存的是实际表的数据,所以我就叫数据页了,接下来因为真正要讲到索引了,所以我就将二级索引的页称为索引页,你知道是同一个,但是存储的数据不一样就可以了。

单列索引

假设,我们现在对name字段加了一个普通非唯一索引,那么name就是索引列,同时name这个索引也就是单列索引。此时如果往表中插入三条数据,那么name索引的叶子节点存的数据就如下图所示

mysql会根据name字段的值进行排序,这里我假设张三排在李四前面,当索引列的值相同时,就会根据id排序,所以索引实际上已经根据索引列的值排好序了。这里肯定有小伙伴疑问,name字段存储的中文也可以排序么?答案是可以的,并且mysql支持很多种排序规则,我们在建数据库或者是建表的时候等都可以指定排序规则,并且后面文章涉及到的字符串排序都是我随便排的,实际情况可能不一样。

对于单个索引列数据查找也是跟前面说的聚簇索引一样,也会对数据分组,之后可以根据二分查找在单个索引列来查找数据。当数据不断增多,一个索引页存储不下数据的时候,也会用多个索引页来存储,并且索引页直接也会形成双向链表

当索引页不断增多是,为了方便在不同索引页中查找数据,也就会抽取一个索引页,除了存页中id,同时也会存储这个id对应的索引列的值

当数据越来越多越来越多,还会抽取,也会形成三层的一个B+树,这里我就不画了。

扫描二维码关注公众号,回复: 15484489 查看本文章

联合索引

除了单列索引,联合索引其实也是一样的,只不过索引页存的数据就多了一些索引列。比如,在name和age上建立一个联合索引,此时单个索引页就如图所示

先以name排序,name相同时再以age排序,如果再有其它列,依次类推,最后再以id排序。相比于只有name一个字段的索引来说,索引页就多存了一个索引列。最后形成的B+树简化为如下图

小结

其实从上面的分析可以看出,聚簇索引和非聚簇索引主要区别有以下几点

  • 聚簇索引的叶子节点存的是所有列的值,非聚簇索引的叶子节点只存了索引列的值和主键id
  • 聚簇索引的数据是按照id排序,非聚簇索引的数据是按照索引列排序
  • 聚簇索引的非叶子节点存的是主键id和页号,非聚簇索引的非叶子节点存的是索引列、主键id、页号

实际情况下索引B+树可能并不是按照我图中画出来的那样排序,但不耽误理解。

原文来自于三友的java日记

猜你喜欢

转载自blog.csdn.net/qq_28165595/article/details/131029916