大厂Mysql高频面试题-!为什么-B+-树比-B-树更适合应用于数据库索引?你回答的上来吗(1)

最后

整理的这些资料希望对Java开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。

image

image

其实面试这一块早在第一个说的25大面试专题就全都有的。以上提及的这些全部的面试+学习的各种笔记资料,我这差不多来回搞了三个多月,收集整理真的很不容易,其中还有很多自己的一些知识总结。正是因为很麻烦,所以对以上这些学习复习资料感兴趣,

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

例如下面的sql语句:

select id from tablename where id == 1;

但是对于这种查找指定范围的sql语句,哈希索引就无能为力了。

select id from tablename where id BETWEEN 20 AND 23;

说明:因为哈希表本身是无序的,所以不利于范围查询

再次思考

到这里我们遇到了一个问题,就是哈希表虽然从查找效率上满足了我们查找单个数据的要求,但是显然,当遇到范围查询时,由于哈希表本身的无序性,不利于指定范围查找。

也就是说,我们的需求增加了,我们希望数据的组织方式,既要有一定规则,又要有序。

在引出这种数据结构之前,我们首先来看一种查找方式:二分查找。

高效的查找方式:二分查找

二分查找的核心思想是给定一个有序的数组,在查找过程中采用跳跃式的方式查找,即先以有序数列的中点位置为比较对象,如果要查找的元素小于中点元素,则将待查序列缩小为左半部分,否则为右半部分。通过每次比较,将查找区间减少一半,直到找到所需元素。

比如要从以下序列中查找到数字4

[1,3,4,5,6,7,8]

需要经过下面的查找步骤:

  • 取中心位置对应元素,显然5大于4,在左边区间[1,3,4]进行查找

  • 继续取中心位置对应元素3,显然3大于4,在右边区间[4]进行查找

  • 4等于4,所以我们查找成功。

可以看到二分查找的效率是O(log n)。

由于有序数组自身的有序性,所以范围查询依然可以通过二分查找的方式查找区间的边界来实现。

这样看来,如果单从查询效率上来说,有序的数组是一种很好的选择。

但是显然有序数组对于插入和删除并不友好,假设我们要插入元素或者删除元素,都需要把部分元素全部向后或者向前移动,最糟糕的时间复杂度是O(n)。

有没有这样一种数据结构,既有一定顺序,又方便插入和删除呢?事实上,基于二分查找的思想,诞生了这样一种数据结构:二分查找树。

基于二分查找思想的二叉查找树

二叉查找树(Binary Search Tree)即BST树是这样的一种数据结构,如下图:

在二叉搜索树中:

1).若任意结点的左子树不空,则左子树上所有结点的值均不大于它的根结点的值。

2).若任意结点的右子树不空,则右子树上所有结点的值均不小于它的根结点的值。

3).任意结点的左、右子树也分别为二叉搜索树。

这样的结构非常适合用二分查找的思维查找元素。

比如我们需要查找键值为8的记录:

  1. 先从根找起,找到6;
  2. 显然8>6,所以接着找到6的右子树,找到7;
  3. 显然8>7, 所以找7的右子树,找到了8,查找结束。

这样一棵子树高度差不大于1的二叉查找树的查找效率接近与O(log n);

但是当二叉树的构造变成这样时,

此时我们再查找8时,查找效率就沦为接近顺序遍历查找的效率。

显然这不是我们想要的,二叉查找树也需要balance。

升级版的BST树:平衡二叉树

我们对二叉查找树做个限制,限制必须满足任何节点的两个子树的最大差为1,也是平衡二叉树的定义,这样我们的查找效率就有了一定的保障。

平衡二叉树(self-balancing binary search tree),又叫AVL树。

当然,维护平衡二叉树也是需要一定开销的,即当树插入/更新/删除新的数据时假设破坏了树的平衡性,那么需要通过左旋和右旋来维护树的平衡。

当数据量很多时,同样也会出现二叉树过高的情况。

我们知道平衡二叉树的查找效率为 O(log n),也就是说,当树过高时,查找效率会下降。

另外由于我们的索引文件并不小,所以是存储在磁盘上的。

文件系统需要从磁盘读取数据时,一般以页为单位进行读取,假设一个页内的数据过少, 那么操作系统就需要读取更多的页,涉及磁盘随机I/O访问的次数就更多。

将数据从磁盘读入内存涉及随机I/O的访问,是数据库里面成本最高的操作之一。

因而这种树高会随数据量增多急剧增加,每次更新数据又需要通过左旋和右旋维护平衡的二叉树,不太适合用于存储在磁盘上的索引文件。

更加符合磁盘特征的B树

前面我们看到,虽然平衡二叉树既有链表的快速插入与删除操作的特点,又有数组快速查找的优势,但是这并不是最符合磁盘读写特征的数据结构。

也就是说,我们要找到这样一种数据结构,能够有效的控制树高,那么我们把二叉树变成m叉树,也就是下图的这种数据结构:B树。

B树是一种这样的数据结构:

1.根结点至少有两个子结点;

2.每个中间节点都包含k-1个元素和k个子结点,其中 m/2 <= k <= m;

3.每一个叶子结点都包含k-1个元素,其中 m/2 <= k <= m;

4.所有的叶子结点都位于同一层;

5.每个结点中关键字从小到大排列,并且当该结点的孩子是非叶子结点时,该k-1个元素正好是k个子结点包含的元素的值域的分划。

可以看到,B树在保留二叉树预划分范围从而提升查询效率的思想的前提下,做了以下优化:

二叉树变成m叉树,这个m的大小可以根据单个页的大小做对应调整,从而使得一个页可以存储更多的数据,从磁盘中读取一个页可以读到的数据就更多,随机IO次数变少,大大提升效率。

但是我们看到,我们只能通过中序遍历查询全表,当进行范围查询时,可能会需要中序回溯。

不断优化的B树:B+树

架构学习资料

准备两个月,面试五分钟,Java中高级岗面试为何越来越难?

准备两个月,面试五分钟,Java中高级岗面试为何越来越难?

准备两个月,面试五分钟,Java中高级岗面试为何越来越难?

准备两个月,面试五分钟,Java中高级岗面试为何越来越难?

准备两个月,面试五分钟,Java中高级岗面试为何越来越难?

由于篇幅限制小编,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

实战项目源码】](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)收录**

需要这份系统化的资料的朋友,可以点击这里获取

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值