B-Tree
- 每个节点最多有 m 个子节点
- 除根节点和叶子节点,其它每个节点至少有 [m/2] (向上取整的意思)个子节点
- 若根节点不是叶子节点,则其至少有2个子节点
- 所有NULL节点到根节点的高度都一样
- 除根节点外,其它节点都包含 n 个key,其中 [m/2] -1 <= n <= m-1
插入demo
-
依次200 ---- 900 …
-
4阶
-
tips
4阶 每个节点不能超过 1 <= n <= 3
- 初始化
200|300|400
- 依次插入
200|300|400|500 <<<< 分裂
300
200 400|500
400
200|300 500 都可以
300
200 400|500|600
300
200 400|500|600|700 <<<< 分裂
300 | 500
200 400 500|600|700
插入 800 900
300 | 500
200 400 600|700|800|900 <<<< 分裂
300 | 500 | 700
200 400 600 800|900
插入910 920
300 | 500 | 700
200 400 600 800|900|910|920<<<<分裂
300 | 500 | 700 | 900 <<<<分裂
200 400 600 800 910|920
树自下而上生长一个高度
500
300 700 | 900
200 400 600 800 910|920
删除demo
- 5阶
- tips
5阶 2<= n <=4
从兄弟和父节点 借
130
40 | 70 170 | 200
10|30 50|60 80|110|120 140|160 180|190 230|240|250|260
- 子节点富足
删除 80 直接删除
130
40 | 70 170 | 200
10|30 50|60 110|120 140|160 180|190 230|240|250|260
删除 230 直接删除
130
40 | 70 170 | 200
10|30 50|60 110|120 140|160 180|190 240|250|260
- 子节点不富足
- 兄弟节点富足
删除 180 右兄弟节点富足 把200放下去 240放上来
130
40 | 70 170 | 240
10|30 50|60 110|120 140|160 190| 200 250|260
- 父节点富足
删除 50
父节点下来40 此时以父节点递归
70
10|30|40|60 110 120
父节点下来 130
70 | 130 | 170 | 240
10|30|40|60 110|120 140|160 190|200 250|260
B+Tree
- 为B-Tree的变种
- 中间节点无数据,只索引,中间节点的元素存在于子节点中是,是子节点的最大 (小)元素
- K个子树的中间节点,有K个元素,
- 叶子节点存储 全部数据 和 指向这些数据的指针
demo
B+Tree
8 | 15
2 | 5 | 8 11 | 15
1|2 >>>> 3|5 >>>> 6|8 >>>> 9|11 >>>> 13|15 有序链表
B-Tree
9
2 | 6 12
1 3|5 8 11 13|15
插入&删除
B+Tree与B-Tree两者大同小异
查找
-
单行查找 3
B-Tree 从跟节点开始比较 小 >>> 左 大 >>> 右 = >>> 指针 无 >>> null B+Tree 自顶向下查3 8|15 >> 2|5|8 >>> 3|5 三次IO -
比较
B+Tree 除了叶子节点都只存储索引,所以一个磁盘块可以存储更多的中间节点,节省IO次数 B+Tree 必须查找到叶子, B-Tree 不稳定,最好为根节点,最差为叶子节点
-
范围查找 3 — 11
B-Tree 遍历到3|5>>> 中序遍历到 6,8,9,11 B+Tree 遍历叶子节点的有序链表 -
比较
显然B+Tree 在范围查找上优势很大
代码实现
这个是个大问题,有时间再补把 - -
mysql 索引上的应用
创建一张student表 字段为
id(primary key) first_name last_name birthday sex score
show index from student
可以看到此时表里已经以 主键id创建了索引
所以即使什么都不做,以id为条件查询速度也很快
- 以其他非索引字段查询会逐行扫描
添加新的索引 注意三个属性的顺序
alert table student
add index f_l_b(first_name,last_name,birthday)
此时以这三个属性建立起了一颗B+Tree 大致如下
f1,l1,b1
f1,l2,b2 f3,l3,b3
参考上面简单版的B+Tree, 把三个属性作为元素带入
索引使用情况
-
where first_name = “f1” and last_name = “l1”
-
where first_name = “f1” and last_name like “cb%”
-
where first_name = “f1” and last_name = “l1” and birthday=“b1”
-
where first_name like “f1%”
三种情况都会使用到索引 -
where last_name = “f2”
-
where first_name like “%f1”
并不会使用到索引,因为并不能按照我们创建的索引顺序去比较,只能全表扫描
mysql索引分析命令
- EXPLAIN select * from student where first_name = “f1”
- 关键字段解释
-
select_type 查询类型
SIMPLE | PRIMARY | UNION | SUBQUERY -
table 数据库表名,按读取顺序
-
type 本数据表与其他数据表的关系
system | const | eq_ref | ref | range | index | All -
possible_keys 可选用的索引
-
key 使用的实际索引
-
key_len 索引按字节计算的长度
-
ref 关联关系中另一个表中数据列的名称
-
rows 查询时预计要读出的数据行树
本文介绍了B-Tree和B+Tree的原理,包括节点子节点数量、key数量等规则。给出了B-Tree的插入和删除示例,B+Tree的插入、删除、查找示例及代码实现。还阐述了B+Tree在MySQL索引上的应用,列举索引使用情况,并介绍了MySQL索引分析命令及关键字段解释。
1344

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



