B+树之浅显易懂

b站讲的好的视频
B树讲的比较好的博客

1、B-树 简介

B-树,也称为B树,是一种平衡的多叉树(可以对比一下平衡二叉查找树),它比较适用于对外查找。

  • 阶数:一个节点最多有多少个孩子节点。(一般用字母m表示)
  • 关键字:节点上的数值就是关键字
  • 度:一个节点拥有的子节点的数量。

一颗m阶的B-树,有以下特征:

  • 根结点至少有两个子女;
  • 每个非根节点所包含的关键字个数 j 满足:m/2 - 1 <= j <= m - 1.(表示向上取整)
  • 有k个关键字(关键字按递增次序排列)的非叶结点恰好有k+1个孩子。
  • 所有的叶子结点都位于同一层。

一棵简单的B-树如下:
在这里插入图片描述

2、B+ 树简介

B+树是B-树的变体,也是一颗多路搜索树。一棵m阶的B+树主要有这些特点:

  • 每个结点至多有m个子女;
  • 非根节点关键值个数范围:m/2 <= k <= m-1
  • 相邻叶子节点是通过指针连起来的,并且是关键字大小排序的。

一颗3阶的B+树如下:
在这里插入图片描述
B+树和B-树的主要区别如下:

  • B-树内部节点是保存数据的;而B+树内部节点是不保存数据的,只作索引作用,它的叶子节点才保存数据。因此在相同的数据量下,B+树更加矮壮
  • B+树相邻的叶子节点之间是通过链表指针连起来的,方便于遍历查询(遍历操作在MySQL中比较常见),而B-树却不是。
  • 查找过程中,B-树在找到具体的数值以后就结束,而B+树则需要通过索引找到叶子结点中的数据才结束
  • B-树中任何一个关键字出现且只出现在一个结点中,而B+树可以出现多次。
  • B树是会在非叶子节点也存储数据,要遍历的时候可能就得跨层检索,相对麻烦些。

B+树与红黑树区别:

  • MySQL的数据是存储在硬盘的,在查询时一般是不能「一次性」把全部数据加载到内存中,而红黑树是「二叉查找树」的变种,一个Node节点只能存储一个Key和一个Value。
  • B和B+树跟红黑树不一样,它们算是「多路搜索树」,相较于「二叉搜索树」而言,一个Node节点可以存储的信息会更多,「多路搜索树」的高度会比「二叉搜索树」更低。
  • 了解了区别之后,其实就很容易发现,在数据不能一次加载至内存的场景下,数据需要被检索出来,选择B或B+树的理由就很充分了(一个Node节点存储信息更多(相较于二叉搜索树),树的高度更低树的高度影响检索的速度

在这里插入图片描述
B+树与哈希表区别:

  • 哈希索引能以 O(1) 时间进行查找,但是失去了有序性。无法用于排序与分组、只支持精确查找,无法用于部分查找和范围查找。
  • InnoDB 存储引擎有一个特殊的功能叫“自适应哈希索引”,当某个索引值被使用的非常频繁时,会在 B+ 树索引之上再创建一个哈希索引,这样就让 B+Tree 索引具有哈希索引的一些优点,比如:快速的哈希查找。

B+树的插入:

  • B+树插入都是在叶子结点进行的,就是插入前,需要先找到要插入的叶子结点。
  • 如果被插入关键字的叶子节点,当前含有的关键字数量是小于阶数m,则直接插入。
  • 如果插入关键字后,叶子节点当前含有的关键字数目等于阶数m,则插,该节点开始 「分裂」为两个新的节点,一个节点包含m/2 个关键字,另外一个关键字包含m/2个关键值。(m/2表示向下取整,m/2表示向上取整,如3/2=2)。
  • 分裂后,需要将第m/2的关键字上移到父结点。如果这时候父结点中包含的关键字个数小于m,则插入操作完成。
  • 分裂后,需要将m/2的关键字上移到父结点。如果父结点中包含的关键字个数等于m,则继续分裂父结点。

3、查找

在一个页中查找:

  • 以主键为搜索条件:在页目录中使用二分法快速定位到对应的槽;然后遍历该槽对应分组中的记录,即可快速找到指定的记录。
  • 以其他列作为搜索条件:从Infimum记录开始依次遍历单向链表中的每条记录,然后对比每条记录是否复合搜索条件。

在很多页中查找:

  • 定位到记录所在页;
  • 从所在的页内查找相应的记录。

如果没有索引,就要遍历每一页,再遍历每组记录。

4、InnoDB与MyISAM区别

  • InnoDB 支持事务,MyISAM 不支持事务。这是 MySQL 将默认存储引擎从 MyISAM 变成 InnoDB 的重要原因之一;
  • InnoDB 支持外键,而 MyISAM 不支持。对一个包含外键的 InnoDB 表转为 MYISAM 会失败;
  • InnoDB 是聚集索引,MyISAM 是非聚集索引。聚簇索引的文件存放在主键索引的叶子节点上,因此 InnoDB 必须要有主键,通过主键索引效率很高。但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据。因此,主键不应该过大,因为主键太大,其他索引也都会很大。而 MyISAM 是非聚集索引,数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的。
  • InnoDB 不保存表的具体行数,执行 select count(*) from table 时需要全表扫描。而MyISAM 用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快;
  • InnoDB 最小的锁粒度是行锁,MyISAM 最小的锁粒度是表锁。一个更新语句会锁住整张表,导致其他查询和更新都会被阻塞,因此并发访问受限。这也是 MySQL 将默认存储引擎从 MyISAM 变成 InnoDB 的重要原因之一;
  • MyISAM存储引擎的数据和索引分开存储,这种存储引擎的索引全部都是二级索引,在叶子节点处存储的是列+行号(对于定长记录格式的记录来说)。

5、搜索区间

  • In操作符的语义与若干个等值匹配操作符(=)之间用OR连接起来的语义是一样的,都会产生多个单点扫描区间。如:
    where key2 in (1434, 6328)
    where key2 = 1434 or key2 = 6328
  • !=产生的扫描区间是(-无穷,a),(a,+无穷);
  • like操作符比较特殊,只有在匹配完整的字符串或者匹配字符串前缀时才产生合适扫描区间。

6、创建和使用索引时注意事项

  • 只为用于搜索、排序或分组的列创建索引;
  • 当列中不重复的值的个数在总记录条数中的占比很大时,才为列建立索引;
  • 索引列的类型尽量小;
  • 可以只为索引列前缀创建索引,以减少索引占用的存储空间;
  • 尽量使用覆盖索引进行查询,以避免回表操作带来的性能损耗;
  • 让索引列以列名的形式单独出现在搜索条件中;
  • 为了尽可能少的让聚簇索引发生页面分裂的情况,建议让主键拥有自增属性;
  • 定位并删除表中的冗余和重复索引。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值