一、数据结构-树
1.概念
树是一种分支结构,不像链表那样是线性结构。典型的树就是二叉树、红黑树等
2.树的相关概念
| 概念 | 含义 |
|---|---|
| 节点 | 树中的每一个元素都是一个节点 |
| 节点的度(阶) | 每一个节点的子节点的个数,也可以说每一个节点的分支数量 |
| 树的度(阶) | 树中所有节点中,拥有"最大度数的节点"的度就是树的度 |
| 叶子节点 | 节点的度为0的节点是叶子节点。也可以说没有子节点的节点就是叶子节点 |
一般形容一棵树会这么形容:一颗最大度数为5的树。或者说一颗最大度数为5阶的树
3.示意图说明
这是一个棵树。
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.对比各种执行方案的代价,找出成本最低的那一个
B树、B+树及其在MySQL索引中的应用
379

被折叠的 条评论
为什么被折叠?



