
文章插图
对应到存储结构上那就是下图:

文章插图
按照上图,我们又添加了一个数据页99,用来保存页32和页124对应的2条目录,现在要查找主键ID为14的记录,需要经历这几个步骤:
- 就从页99中,快速检索到对应的目录项数据页124;
- 在页124中,快速检索到对应的数据页27;
- 在页27中,快速检索到主键为14的记录 。
B+树最底层的节点(对应图中存储用户记录的数据页)被称为叶子节点,其他的节点自然叫做非叶子节点了,更特殊地,B+树最顶部的节点叫做根节点 。
有一个值得我们关注的细节,这棵B+树的叶子节点存储了我们完整的用户记录(就是我们插入表的所有数据),而且,这是用户记录在InnoDB引擎中的唯一存储方式 。也就是所谓的“索引即数据,数据即索引” 。
更方便地一点是,这个关于主键的索引完全是由InnoDB存储引擎自动生成的,不需要我们显式地书写创建索引的语句 。这个索引叫做主键索引,又叫做聚簇索引 。
主键索引有两个特点:
- 按照主键的大小对用户记录和数据页进行排序,记录用单向链表连接,数据页使用双向链表连接;
- B+树的叶子节点保存了用户的完整记录 。
3.2 普通索引主键索引是在搜索条件为主键的时候才会发挥作用,但是我要以name='蝉沐风'为搜索条件怎么办?通过主键索引的讲解,我们首先会想到这么一个方案:再创建一个B+树(我们称为name索引),其中用户记录和数据页按照name字段进行排序,B+树的叶子节点保留完整的用户数据,这样就可以实现对name列的快速搜索了 。
但是如此一来,表中数据就被完整记录了2次(主键索引的叶子节点和name索引的叶子节点),要是我们为其他字段再建立索引,磁盘空间可想而知 。因此,我们得想个其他的办法 。
我们已经知道根据主键查询用户记录是非常快的了,那我们可以想个办法根据name字段来迅速找到主键,然后再根据主键查找用户记录啊 。这个办法同样离不开B+树 。

文章插图
这棵B+树和聚簇索引的B+树有点区别:
- 叶子节点存放的不再是完整的用户记录,而是只记录name列和主键值;
- 数据页中存放的用户记录和目录项记录由原本的按照主键排序变为按照name列排序;
- 目录项记录除了存储索引列(name)和页号之外,同时还存储了主键值;(大家可以想一想,为什么要存储主键值)
你可能对字符串进行二分法感到有点奇怪,甚至没有接触过的相关知识的读者连对字符串进行排序都会觉得很诧异 。其实在创建表的时候我们可以对字符串字段指定字符集和比较规则,如果你不指定,MySQL会默认给你设置,总之,MySQL总会找到一个方式对字符串进行排序 。现在得到主键的id了,然后根据主键id到主键索引中查找到完整的用户记录,这个过程叫做回表 。如果没有为name列设置唯一性约束,那就可能找到多个符合条件的主键id,多回几次表就可以了 。
对name这种单个列添加的索引叫做普通索引,也叫二级索引 。
如果同时对多个列建立索引,那B+树的存储又会是什么样子呢?这就是联合索引了,理解了上面的内容,再理解联合索引只是水到渠成的事罢了 。
3.3 联合索引假设我们为name列和phone列建立联合索引(注意我描述的顺序),自然也是创建一棵B+树,这棵B+树和之前又稍微有点不同:
- 叶子节点存放的是name列、phone列和主键值;
- 目录项记录除了存储索引列(name、phone)和页号之外,同时还存储了主键值;(大家可以想一想,为什么要存储主键值)
推荐阅读
- 换了那么多台电脑,这四款高质量软件,从不离身,装机必备
- 电脑上网正常,网络图标却显示异常?
- 荣耀水晶|买皮肤送“水晶”,精确计算上架多少款皮肤,可白嫖荣耀水晶
- 金泰妍|从太妍到泫雅韩,为何倒V拍照手势在韩国引潮流?
- 上火吃什么好 六款药膳利湿解毒消烦祛火
- 哪种电瓶车质量是最好的?
- 扁桃体发炎喝板蓝根有什么用
- 扬州|白领午休场面引热议,躺在工位上小憩,网友嘲:跟“厂妹”没啥区别
- 厕所|重庆一景区设“秋千厕所” 秋千悬空坐便器上方吸睛:旧梗重提 还有鱼缸厕所等
- 野山红茶喜上楣,野山乔茶的功效与作用
