我们上章讲的B+树实现原理就是用的聚簇索引为例子来讲解。讲解二者的区别,我们首先对二者分别进行分析。
聚簇索引
特点:
- 索引和数据保存在一个B+树中。
- 数据项是按照主键大小排列成的一个单链表
- 页和页之间也是根据页内中主键值的大小排列成双向链表的
- 叶子节点存储的是完整的数据
- 非叶子节点存储的是主键+页号(根据上节图例)。
优点:
- 数据访问快,如果我们用主键查找数据,那么就会直接找到数据。而非聚簇索引需要一次回表操作。这也是为什么聚簇索引的效率高于非聚簇索引
- 聚簇索引对于主键的排序查找和范围查找效率更快。因为数据项是按照顺序排列,并且页和页之间是双向链表。
缺点:
- 查找效率高的同时,插入,修改操作的效率也会降低了,如果插入一个id大小十分乱的数据,那么还要根据顺序,把该数据放在指定位置。所以我们一般会定义一个自增的主键。 修改也是,当修改主键值时,也会造成数据的迁移。所以我们并不建议修改主键值。
非聚簇索引
下面这图是不是很熟悉,在之前讲B+树实现原理时,我们用到了聚簇索引的图,这里是非聚簇索引的图。二者都是B+树,所以非常的相似。区别就是非聚簇索引的叶子节点不再存储完整数据,只存储索引字段+主键,我们在找到对应主键时,还要进行一次回表操作,就是拿到该主键,再走一遍聚簇索引,最后才能拿到完整的数据。
以上的非聚簇索引并不是最完整的,我们思考一个问题,我们在为其他字段创建索引时,并不能保证该字段为唯一的,也就是说该字段可能会有许多重复的。那么我们在增加一条重复字段时,以下图为例,我们增加一个(9,1,“c”)的数据,那么在修改c2列索引的时候,在页3查找的时候蒙了,不知道该去页4还是页5,所以我们还应该保证目录项的唯一性。
怎样来保证目录项的唯一性呢,这里是通过把主键值也加入到目录项中,那么这条目录项也将唯一了。那么在增加(9,1,“c”)这条记录时,就会通过对比,发现9>7 应该放在页5中。