mysql8.0基础-索引2(六)

B树、B+树及其在MySQL索引中的应用

一、数据结构-树

1.概念

树是一种分支结构,不像链表那样是线性结构。典型的树就是二叉树、红黑树等

2.树的相关概念

概念含义
节点树中的每一个元素都是一个节点
节点的度(阶)每一个节点的子节点的个数,也可以说每一个节点的分支数量
树的度(阶)树中所有节点中,拥有"最大度数的节点"的度就是树的度
叶子节点节点的度为0的节点是叶子节点。也可以说没有子节点的节点就是叶子节点

一般形容一棵树会这么形容:一颗最大度数为5的树。或者说一颗最大度数为5阶的树

3.示意图说明

这是一个棵树。

A1
A2
A3
A4
A5
A6
A7

3.1 节点

A1-A7每一个都是一个节点

3.2 节点的度

A1的度为3
A2的度为2
A3的度为0
A4的度为1
A5,A5的度都为0

3.3 树的度

树的度为3,因为其中A1的度最大为3,所以树的度就为3

3.4 叶子节点

A3,A5,A6,A7都为叶子节点,因为他们的度都为0

二、B-tree

1.B树的由来

对于大量数据来说,如果组成二叉树,树的层级(高度)会变的很高,检索效率就会很低。所以就有了B-tree

2.B树的特点

B树叫做"多路平衡搜索树"。有以下几个特点

2.1 多路

(1)一个节点可以有多个子节点(分支),节点内有 "子节点数 - 1"个元素。
比如:一个节点有6个子节点。那么这个节点内最多可以有5个元素(数据)

(2)为什么节点内的元素会比子节点数量少1呢:
因为为了维护各个节点之间的关系。一个节点内要有数据,还要有指向各子树的指针。比如最大度数为3阶的B树结构如下:
在这里插入图片描述

节点3,度数为3,所以节点内有两个元素,就是子节点数量-1

2.2 平衡

平衡是指的所有的叶子节点都在一层

2.3 有序

有序是指任意一个节点的左子节点小于它,右子节点大于它

3.B树的问题

当我们要按照顺序遍历所有元素时,需要用中序遍历方法来查询。这样效率就很低。

三、B+tree

B+树就解决了按照顺序查找所有元素效率低的问题。B+树在B树的基础上进行了改良.如下图:

在这里插入图片描述

1.叶子节点

(1)B+树的叶子节点,包含了所有的节点内的元素
(2)所有叶子节点都是从小到大链接起来。用指针形成了一个单向链表结构

2.裂变过程

可以通过下边这个网站查看B+树的裂变过程

https://www.cs.usfca.edu/~galles/visualization/Algorithms.html

四、B-tree和B+tree索引

在上边只是单独讲了B树和B+树的数据结构。下边讲解一下他们分别作为mysql的索引的结构是什么样的。

1.B树索引

B树结构作为索引的示意图:每个节点都带有数据。
带的是什么数据,主要看这个索引是聚集索引还是非聚集索引。具体看上一篇文章

在这里插入图片描述

2.B+树索引

B+树结构作为索引的示意图:每个叶子节点都带有数据。索引节点不在带有数据
mysql对经典的B+树进行了优化,在原来的基础上,增加了一个指向相邻叶子节点的链表指针,就行成了带有顺序指针的B+树,提高了区间的访问性能

在这里插入图片描述

3.有序特点

在数据结构中的有序指的是节点的左子节点小于它,右子节点大于它。
在B+树索引中,不仅继承了上述的有序特点,这里的有序还包含了叶子节点也是排好序的

4.innodb的存储单位

innodb的存储单位从大到小的如下:

表空间 >>>>

innodb和磁盘交互的最小单位就是页。当需要读一条记录的时候,并不是将这个记录本身从磁盘读出来,而是以页为单位,将其整体读入内存。

5.查看mysql页的大小

一个页的大小在mysql中是16KB的大小。此选项默认单位是字节

mysql> show variables like "innodb_page_size";
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| innodb_page_size | 16384 |
+------------------+-------+
1 row in set (0.01 sec)

在上边的数据结构中,其实每一个节点就是一个页

六.面试题

1.三层的B+数可以存多少树

此答案是根据腾讯开发者社区的一篇文章而来。
简单回答:大约2000W数据。

1.1 计算一个叶子节点可以存多少数据

一个页的大小为16KB.假设mysql中一行数据的总大小为1kb。(实际上现在很多互联网业务数据记录大小通常就是 1K 左右)
那么"一个叶子节点"的页可以存储 16 / 1 = 16行的数据

2.2 计算一个非叶子节点可以存多少key和指针

建设主键id为bigint类型,大小为8字节。指针在innodb存储引擎中设置为6字节。一共14字节。那么一页中能存放多少这样的数据
16384字节 / 14字节 = 1170

2.3 两层B+树的存储的数据

16 * 1170 = 18720条数据

2.3 三层B+树的数据

16 * 1170 * 1170 = 21,902,400 条数据

2.mysql索引为什么使用B+树,而不使用B树或者其它树形

简单说:因为 B 树不管叶子节点还是非叶子节点,都会保存数据。这样导致非叶子节点中能保存的指针数量变少。
指针数量变少的情况,在保存大量的数据,那么树的高度就会变高,导致IO操作变多。查询性能变低

3.明明创建了索引,但是没有生效

3.1 使用原则的问题

这个原因就是sql编写的问题,具体见上一篇文档

3.2 查询优化器的问题

查询优化器大致的优化过程是:
1.根据搜索条件,找出所有可能使用的索引
2.计算全表扫描的代价
3.计算使用不同索引执行查询的代价
4.对比各种执行方案的代价,找出成本最低的那一个

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值