016 MySQL中B+Tree,从二叉树、平衡二叉树、B-Tree讲起

学软件技术,读第一手资料,去官方网站:MySQL 5.7参考手册

也可以看看比较经典的书籍,如《高性能MySQL》等


MySQL中表里面的数据越来越大的时候,查询数据就会变慢,为了解决查询变慢的问题常用的办法是在表上建索引,然后根据索引查询数据就会更快。

MySQL中,用的最多的是InnoDB存储引擎,InnoDB中的索引采用B+Tree这种数据结构。B+Tree 索引是 B+Tree 在数据库的一种实现。B+Tree 中的B代表平衡(balance),而不是二叉(binary),因为 B+Tree 是从 “平衡二叉树” 再经过 “B树(B-Tree)” 一步步演化而来的。

在讲 B+Tree 之前必须先了解二叉树、平衡二叉树(AVL Tree)和平衡多路查找树(B-Tree)。

(1)二叉树(Binary Search Trees,二叉查找树);

(2)平衡二叉树(或者叫AVL Tree),是1962年由G. M. Adelson-Velsky和E. M. Landis共同提出的一种数据结构。AVL是作者名字的缩写。在二叉搜索树的基础上加上平衡的限制便是AVL树,所以AVL树也可以叫BBST,Balanced Binary Search Tree;

(3)平衡多路查找树(B-Tree,读作“B树”,别读成“B减树”,也别读成“B杠树”);

(4)B+树(,读作“B加树”)。

1、二叉树

二叉树,分2个叉的树,左子树的键值 < 根的键值 < 右子树的键值,且节点中存储了键(key)和数据(data),二叉树数据分布不均匀的时候会退化成链表

数据库中的数据基本都是放在磁盘中的,每读取一个二叉树的结点就是一次磁盘IO。

1.1 数据分布很好的情况如下,查询其中的数据IO次数稳定:

1.2 数据分布不好的情况,查找数据IO次数不稳定,比如要找(17,dy)这条数据就需要IO次数很多,数据结构退化成链表

 2、平衡二叉树

为了 防止 二叉树退化成链表 的最坏的情况,在符合二叉查找树的条件下,还满足任何节点的两个子树的高度最大差为1,这样就变成平衡二叉树(AVL树),需要注意的是平衡二叉树是每个节点只存储一个键值和数据的。

为了保证任何节点的两个子树的高度最大差为1,是通过各种旋转,具体细节不在本文档的讨论范围。如下:

数据量很大的时候,因为每个节点只存储一个键值和数据,所以树的高度就会很高,树高度很高就会使得查询磁盘IO次数变多,IO次数多查询就变慢了。

3、B-Tree

B-Tree 和平衡二叉树不一样,B-Tree 属于多叉树又名平衡多路查找树(查找路径不止两个)。

平衡二叉树 每个节点只有一个key,而多路合并之后的B-Tree每个节点含有一组key。这样整棵树的层级会变矮,可以针对外部查找大大减少I/O次数。这就解释了为什么已经有了  “平衡二叉树” 还弄个B-Tree。

 

B-Tree 特点:

(1)B-Tree每个节点含有一组key(而 平衡二叉树 每个节点只有一个key),这样压缩树的高度 ,减少I/O次数,提升查询速度

(2)叶子节点具有相同的深度(同B+Tree),页节点指针为空(B+Tree叶子节点有指针连接)

(3)所有索引元素不重复(B+Tree中非叶子节点有key的冗余),非叶子节点上有数据

(4)节点中的索引从左到右递增排列

4、B+Tree

B+Tree是在B-Tree基础上的一种优化,使其更适合实现外存储索引结构。B+Tree与B-Tree的结构很像,但是也有几个自己的特性:

(1)叶子节点具有相同的深度(同B-Tree),所有叶子节点之间都有一个链指针

(2)所有的非叶子节点只存储关键字(key)信息

(3)所有数据都存在叶子结点

(4)节点中的索引从左到右递增排列

5、 MySQL为什么最终要去选择B+Tree?

    (1)B+Tree是B-Tree的变种,B-Tree能解决的问题,B+Tree也能够解决(降低树的高度,增大节点存储数据量)

    (2)B+Tree扫库和扫表能力更强。如果我们要根据索引去进行数据表的扫描,对B-Tree进行扫描,需要把整棵树遍历一遍,而B+TREE只需要遍历他的所有叶子节点即可(叶子节点之间有引用)。

   (3)B+Tree磁盘读写能力更强。他的根节点和支节点不保存数据区,所以根节点和支节点同样大小的情况下,保存的关键字要比B-Tree要多。所以,B+Tree读写一次磁盘加载的关键字比B-Tree更多。

   (4)B+Tree排序能力更强。上面的图中可以看出,B+Tree天然具有排序功能。

   (5)B+Tree查询性能稳定。B+Tree数据只保存在叶子节点,每次查询数据,查询IO次数一定是稳定的。当然这个每个人的理解都不同,因为在B-Tree如果根节点命中直接返回,确实效率更高。

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值