FantasticMao 技术笔记
BlogGitHub
  • README
  • C & Unix
    • C
      • 《C 程序设计语言》笔记
      • C 语言中的陷阱
      • CMake 示例
      • GNU make
      • LLVM Clang
      • Nginx 常用模块
      • Vim 常用命令
    • Unix-like
      • 《深入理解计算机系统》笔记
      • 《UNIX 环境高级编程》笔记 - UNIX 基础知识
      • 《UNIX 环境高级编程》笔记 - 文件 IO
      • 《UNIX 环境高级编程》笔记 - 标准 IO 库
      • 《鳥哥的 Linux 私房菜》笔记 - 目录配置
      • 《鳥哥的 Linux 私房菜》笔记 - 认识与学习 bash
      • 《鳥哥的 Linux 私房菜》笔记 - 任务管理
      • OpenWrt 中的陷阱
      • iptables 工作机制
  • Go
    • 《A Tour of Go》笔记
    • Go vs C vsJava
    • Go 常用命令
    • Go 语言中的陷阱
  • Java
    • JDK
      • 《Java 并发编程实战》笔记 - 线程池的使用
      • 设计模式概览
      • 集合概览
      • HashMap 内部算法
      • ThreadLocal 工作机制
      • Java Agent
    • JVM
      • 《深入理解 Java 虚拟机》笔记 - Java 内存模型与线程
      • JVM 运行时数据区
      • 类加载机制
      • 垃圾回收算法
      • 引用类型
      • 垃圾收集算法
      • 垃圾收集器
    • Spring
      • Spring IoC 容器扩展点
      • Spring Transaction 声明式事务管理
      • Spring Web MVC DispatcherServlet 工作机制
      • Spring Security Servlet 实现原理
    • 其它
      • 《Netty - One Framework to rule them all》演讲笔记
      • Hystrix 设计与实现
  • JavaScript
    • 《写给大家看的设计书》笔记 - 设计原则
    • 《JavaScript 权威指南》笔记 - jQuery 类库
  • 数据库
    • ElasticSearch
      • ElasticSearch 概览
    • HBase
      • HBase 数据模型
    • Prometheus
      • Prometheus 概览
      • Prometheus 数据模型和指标类型
      • Prometheus 查询语法
      • Prometheus 存储原理
      • Prometheus vs InfluxDB
    • Redis
      • 《Redis 设计与实现》笔记 - 简单动态字符串
      • 《Redis 设计与实现》笔记 - 链表
      • 《Redis 设计与实现》笔记 - 字典
      • 《Redis 设计与实现》笔记 - 跳跃表
      • 《Redis 设计与实现》笔记 - 整数集合
      • 《Redis 设计与实现》笔记 - 压缩列表
      • 《Redis 设计与实现》笔记 - 对象
      • Redis 内存回收策略
      • Redis 实现分布式锁
      • Redis 持久化机制
      • Redis 数据分片方案
      • 使用缓存的常见问题
    • MySQL
      • 《高性能 MySQL》笔记 - Schema 与数据类型优化
      • 《高性能 MySQL》笔记 - 创建高性能的索引
      • 《MySQL Reference Manual》笔记 - InnoDB 和 ACID 模型
      • 《MySQL Reference Manual》笔记 - InnoDB 多版本
      • 《MySQL Reference Manual》笔记 - InnoDB 锁
      • 《MySQL Reference Manual》笔记 - InnoDB 事务模型
      • B-Tree 简述
      • 理解查询执行计划
  • 中间件
    • gRPC
      • gRPC 负载均衡
    • ZooKeeper
      • ZooKeeper 数据模型
    • 消息队列
      • 消息积压解决策略
      • RocketMQ 架构设计
      • RocketMQ 功能特性
      • RocketMQ 消息存储
  • 分布式系统
    • 《凤凰架构》笔记
    • 系统设计思路
    • 系统优化思路
    • 分布式事务协议:二阶段提交和三阶段提交
    • 分布式系统的技术栈
    • 分布式系统的弹性设计
    • 单点登录解决方案
    • 容错,高可用和灾备
  • 数据结构和算法
    • 一致性哈希
    • 布隆过滤器
    • 散列表
  • 网络协议
    • 诊断工具
    • TCP 协议
      • TCP 报文结构
      • TCP 连接管理
由 GitBook 提供支持
在本页
  • 度的定义
  • 节点内部
  • 维持平衡
  • 参考资料
  1. 数据库
  2. MySQL

B-Tree 简述

最后更新于1年前

度的定义

B-Tree 预定义了一个「树的度(degree )」的范围。当在节点中插入或删除数据时,「节点的度」就会变化,但仅限制在 B-Tree 预定义的范围之内变化。

为了维持预定义的「树的度」的范围,B-Tree 的内部节点可能被合并或分离。因为「节点的度」可以在一定范围内盖改变,所以 B-Tree 可以不像其它「自平衡搜索树」一样,需要经常重新平衡树的内部节点。不过 B-Tree 可能会浪费一些存储空间,因为它的内部节点可能是不满的。

B-Tree 「树的度」的上限和下限,对某一特定的实现来说通常是固定的。例如 2-3 B-Tree 的每一个内部节点的度仅可能只有 2 或 3 个子节点。

节点内部

每个 B-Tree 的内部节点可以包含多个 key,key 用作为分离内部节点的「子树」的分离值。例如,如果一个 B-Tree 的内部节点拥有 3 个子节点(即子树),那么它就有拥有 2 个 key :a1 和 a2。左侧子树中的 key 小于 a1,中部子树中的 key 大于 a1 并小于 a2,右侧子树中的 key 大于 a2。

通常来说,key 的个数会介于 d ~ 2d 之间,d+1 是「树的度」。在实际应用中,key 往往占用了节点的大部分空间。系数 2 可以保证节点被正常分离或组合。当向一个拥有 2d 个 key 的内部节点添加一个 key 时,B-Tree 将会这 2d+1 个 key 分离成 2 节点,并且将处于中间位置的 key 移动至父节点中。至此,每个被分离的节点都拥有最小数量的 key。类似的,当向两个相邻且都拥有 d 个 key 的内部节点删除一个 key 时,B-Tree 则会组合这两个相邻的节点。删除一个 key 会导致内部节点仅有 d-1 个 key。组合两个相邻的节点时,会从其父节点中取出一个 key 与它们组成一个拥有 2d 个 key 的节点。

节点的「子树」个数会比节点的 key 个数多一个。在 2-3 B-Tree 中,内部节点将会存储 1 个或 2 个 key,同时会存储 2 个子树或 3 个子树。一棵 B-Tree 树的上限和下限,有时候会被参数化成 (d + 1) - (2d + 1) ,或者更简单地仅以 (2d + 1) 来描述。

维持平衡

B-Tree 通过要求所有的「叶子节点」都保持相同的深度,来维持树的平衡。「树的深度」会随着元素的添加而缓慢增加,然而 B-Tree 「树的深度」整体性的增加是不常见的,这会导致树中所有的「叶子节点」离「树根」更远了一个节点。

参考资料

B数 - 维基百科