针对主键之外的字段建立的二级索引,又是如何运作的?

基于主键的数据搜索非常清晰了,其实就是从聚簇索引的根节点开始进行二分查找,一路找到对应的数据页里,基于页目录就直接定位到主键对应的数据就可以了,这个其实很好理解。接着又会有另外一个疑惑了,那就是如果想要对其它的字段建立索引,甚至是基于多个字段建立联合索引,此时这个索引结构又是如何的呢?

假设要是针对其它字段建立索引,比如name、age之类的字段,这都是一样的原理,简单来说,比如你插入数据的时候,一方面会把完整数据插入到聚簇索引的叶子节点的数据页里去,同时维护好聚簇索引,另一方面会为你其它字段建立的索引,重新再建立一颗B+树。比如基于name字段建立了一个索引,那么此时插入数据的时候,就会重新搞一颗B+树,B+树的叶子节点也是数据页,但是这个数据页里仅仅放主键字段和name字段,具体如下图所示:
在这里插入图片描述
这可是独立于聚簇索引之外的另外一个索引B+树了,严格来说是name字段的索引B+树,所以在name字段的索引B+树里,叶子节点的数据页里仅仅放主键和name字段的值,至于排序规则之类的,都是跟以前的一样的。也就是说,name字段的索引B+树里,叶子节点的数据页中的name值都是按大小排序的,同时下一个数据页里的name字段值都大于上一个数据页里的name字段值,这个整体的排序规则都跟聚簇索引按照主键的排序规则是一样的。

然后呢,name字段的索引B+树也会构建多层级的索引页,这个索引页里存放的就是下一层的页号和最小name字段值,整体规则都是一样的,只不过存放的都是name字段的值,根据name字段值排序罢了,如下图所示:
在这里插入图片描述
假设要根据name字段来搜索数据,那搜索过程简直都一样了,不就是从name字段的索引B+树里的根节点开始找,一层一层往下找,一直找到叶子节点的数据页里,定位到name字段值对应的主键值。然后呢?此时针对select * from table where name='xx’这样的语句,先根据name字段值在name字段的索引B+树里找,找到叶子节点也仅仅可以找到对应的主键值,而找不到这行数据完整的所有字段。

所以此时还需要进行“回表”,这个回表,就是说还需要根据主键值,再到聚簇索引里从根节点开始,一路找到叶子节点的数据页,定位到主键对应的完整数据行,此时才能把select *要的全部字段值都拿出来。

因为根据name字段的索引B+树找到主键之后,还要根据主键去聚簇索引里找,所以一般把name字段这种普通字段的索引称之为二级索引,一级索引就是聚簇索引,这就是普通字段的索引的运行原理。其实也可以把多个字段联合起来,建立联合索引,比如name+age。此时联合索引的运行原理也是一样的,只不过是建立一颗独立的B+树,叶子节点的数据页里放了id+name+age,然后默认按照name排序,name一样就按照age排序,不同数据页之间的name+age值的排序也如此。

然后这个name+age的联合索引的B+树的索引页里,放的就是下层节点的页号和最小的name+age的值,以此类推,所以当根据name+age搜索的时候,就会走name+age联合索引的这颗B+树了,搜索到主键,再根据主键到聚簇索引里去搜索。

以上,就是innodb存储引擎的索引的完整实现原理了,其实一步一步看下来,会发现索引这块知识也没那么难,不过就是建立B+树,根据B+树一层一层二分查找罢了,然后不同的索引就是建立不同的B+树,然后增删改的时候,一方面在数据页里更新数据,一方面就是维护所有的索引。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值