树(8)B+树

Published on with 0 views and 0 comments

B+ 树简介

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

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

一颗 3 阶的 B+ 树如下:
image202204081326349txpshq.png

B+ 树和 B-树的主要区别如下:
  • B-树内部节点是保存数据的;而 B+ 树内部节点是不保存数据的,只作索引作用,它的叶子节点才保存数据。
  • B+ 树相邻的叶子节点之间是通过链表指针连起来的,B-树却不是。
  • 查找过程中,B-树在找到具体的数值以后就结束,而 B+ 树则需要通过索引找到叶子结点中的数据才结束
  • B-树中任何一个关键字出现且只出现在一个结点中,而 B+ 树可以出现多次。

B+ 树经典面试题

  • InnoDB 一棵 B+ 树可以存放多少行数据?

    在文件系统中,最小单位是块,一个块大小就是 4k;

    InnoDB 存储引擎最小储存单元是页,一页大小就是 16k。

    因为 B+ 树叶子存的是数据,内部节点存的是键值 + 指针。索引组织表通过非叶子节点的二分查找法以及指针确定数据在哪个页中,进而再去数据页中找到需要的数据;

    假设 B+ 树的高度为 2 的话,即有一个根结点和若干个叶子结点。这棵 B+ 树的存放总记录数为=根结点指针数*单个叶子节点记录行数。

    如果一行记录的数据大小为 1k,那么单个叶子节点可以存的记录数 =16k/1k =16.

    非叶子节点内存放多少指针呢?我们假设主键 ID 为 bigint 类型,长度为 8 字节,而指针大小在 InnoDB 源码中设置为 6 字节,所以就是 8+6=14 字节,16k/14B =16*1024B/14B = 1170

    因此,一棵高度为 2 的 B+ 树,能存放 1170 * 16=18720 条这样的数据记录。同理一棵高度为 3 的 B+ 树,能存放 1170 *1170 *16 =21902400,也就是说,可以存放两千万左右的记录。B+ 树高度一般为 1-3 层,已经满足千万级别的数据存储。

  • 为什么索引结构默认使用 B+ 树,而不是 hash,二叉树,红黑树,B-树?

    简单版回答如下:

    • Hash 哈希,只适合等值查询,不适合范围查询。
    • 一般二叉树,可能会特殊化为一个链表,相当于全表扫描。
    • 红黑树,是一种特化的平衡二叉树,MySQL 数据量很大的时候,索引的体积也会很大,内存放不下的而从磁盘读取,树的层次太高的话,读取磁盘的次数就多了。
    • B-Tree,叶子节点和非叶子节点都保存数据,相同的数据量,B+ 树更矮壮,也是就说,相同的数据量,B+ 树数据结构,查询磁盘的次数会更少。

插入和删除就不展开了,因为太多了,面试的话,只记住这些应该足够了吧。。

具体的可以参考这篇文章:
MySQL 索引底层:B+ 树详解 - 知乎 (zhihu.com)


标题:树(8)B+树
作者:cuijianzhe
地址:https://cjzshilong.cn/articles/2022/04/08/1649401457496.html