B树与B+树

B树定义

  • 每个节点最多有m-1个关键字(可以存有的键值对,m表示树的高度)
  • 根节点最少可以只有1个关键字
  • 非根节点至少有m/2个关键字
  • 每个节点中的关键字都按照从小到大的顺序排列,每个关键字的左子树中的所有关键字都小于它,而右子树中的所有关键字都大于它
  • 所有叶子节点都位于同一层,或者说根节点到每个叶子节点的长度都相同
  • 每个节点都存有索引和数据,也就是对应的key和value

B+树定义

  • 根节点至少一个元素
  • 非根节点元素范围:m/2 <= k <= m-1
  • B+树有两种类型的节点:内部结点(也称索引结点)和叶子结点。内部节点就是非叶子节点,内部节点不存储数据,只存储索引,数据都存储在叶子节点。
  • 内部结点中的key都按照从小到大的顺序排列,对于内部结点中的一个key,左树中的所有key都小于它,右子树中的key都大于等于它。叶子结点中的记录也按照key的大小排列。
  • 每个叶子结点都存有相邻叶子结点的指针,叶子结点本身依关键字的大小自小而大顺序链接。
  • 父节点存有右孩子的第一个元素的索引。

B树和B+树的区别

1、磁盘读写代价更低

一般来说B+Tree比BTree更适合实现外存的索引结构,因为存储引擎的设计专家巧妙的利用了外存(磁盘)的存储结构,即磁盘的最小存储单位是扇区(sector),而操作系统的块(block)通常是整数倍的sector,操作系统以页(page)为单位管理内存,一页(page)通常默认为4K,数据库的页通常设置为操作系统页的整数倍,因此索引结构的节点被设计为一个页的大小,然后利用外存的“预读取”原则,每次读取的时候,把整个节点的数据读取到内存中,然后在内存中查找,已知内存的读取速度是外存读取I/O速度的几百倍,那么提升查找速度的关键就在于尽可能少的磁盘I/O,那么可以知道,每个节点中的key个数越多,那么树的高度越小,需要I/O的次数越少,因此一般来说B+Tree比BTree更快,因为B+Tree的非叶节点中不存储data,就可以存储更多的key。

2、查询速度更稳定

由于B+Tree非叶子节点不存储数据(data),因此所有的数据都要查询至叶子节点,而叶子节点的高度都是相同的,因此所有数据的查询速度都是一样的。

3、所有的叶子节点形成了一个有序链表,更加便于查找。(范围查找比B树有优势)

磁盘寻址毫秒级别,内存是纳秒级别。(秒,毫秒,微秒,纳秒)

磁盘读:寻道时间(磁头沿径向移动,移到要读取的扇区所在磁道的上方)+ 旋转延迟时间(盘片旋转,使得要读取的扇区转到读写磁头的下方)+ 传输时间(读写数据时间)

连续I/O:本次 I/O 给出的初始扇区地址和上一次 I/O 的结束扇区地址是完全连续或者相隔不多的。做连续 I/O 的时候,磁头几乎不用换道,或者换道的时间很短;而对于随机 I/O,如果这个 I/O 很多的话,会导致磁头不停地换道,造成效率的极大降低

磁盘IO与预读:当一次IO时,不光把当前磁盘地址的数据,而是把相邻的数据也都读取到内存缓冲区内。每一次IO读取的数据我们称之为一页(page)

B+树数据存储

非叶子节点能存多少数据

  • 页默认16KB
  • File Header、Page Header等一共占102个字节
  • Infimum + Supremum分别占13个字节
  • 记录头占5个字节
  • id占为int,占4个字节
  • 页目录的偏移量占4个字节

叶子节点能存多少数据

  • 变长列表占1个字节
  • null标志位忽略
  • 记录头占5个字节
  • id占为int,占4个字节
  • name为VARCHAR,编码为UTF8,为了好算,所有行记录我都只用两个中文,那就是 2 * 3B = 6个字节
  • 事务ID列占6个字节
  • 回滚指针列占7个字节

附:

3层B+树可以存多少数据

B+树的每个节点可以存16KB数据,这里我们假设我们的一行数据大小是1K,那么我们一个节点就可以存16行数据。

非叶子节点存放的是主键值与指针,所以这里假设主键类型为bigint,占用8Byte,指针可以设置为占用6Byte,总共就为14Byte,这样就可以算出一个节点大概可以存放多少个指针了(指针指向下一层节点),大概为16KB/14Byte=1170个。2层B+树的话,可以存放1170*16=18720行数据。3层B+树的话,可以存放1170*1170*16=21902400行数据,也就差不多2000w条数据了。

参考文章

漫画叙述B+树和B-树,很值得看!_漫画叙述b+树和b-树,很值得看!-CSDN博客

mysql为什么用B+树_扁豆小夜博客-CSDN博客

为什么 MySQL 使用 B+ 树

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/6616.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

arm 交叉编译 thumb 与 arm 指令的方法

arm 交叉编译 thumb 与 arm 指令的方法 本文实现了在 x86 的 ubuntu 的机器上&#xff0c;使用 arm-linux-gnueabihf-gcc 交叉编译链工具&#xff0c;编译出在 arm 开发板上可以运行的 thumb 指令集的可执行文件。后续会使用 vscode 使用网络进行远程调试。 1. 编译器 arm-li…

高等代数复习:可对角化

文章目录 可对角化定义可对角化的刻画 本篇文章适合个人复习翻阅&#xff0c;不建议新手入门使用 可对角化 定义 定义&#xff1a;可对角化的线性映射 若 n n n 维线性空间 V V V 上的线性变换 φ \varphi φ 在某组基 { e 1 , e 2 , … , e n } \{e_1,e_2,\dots,e_n\} {…

如何将 redis 快速部署为 docker 容器?

部署 Redis 作为 Docker 容器是一种快速、灵活且可重复使用的方式&#xff0c;特别适合开发、测试和部署环境。本文将详细介绍如何将 Redis 部署为 Docker 容器&#xff0c;包括 Docker 安装、Redis 容器配置、数据持久化、网络设置等方面。 步骤 1&#xff1a;安装 Docker 首…

【Python异常处理】

文章目录 一、什么是异常&#xff1f;二、Python的异常处理机制三、异常处理示例1. 简单异常处理2. 捕获多个异常3. 使用else和finally 四、抛出异常 一、什么是异常&#xff1f; 异常指的是程序在执行过程中遇到的非正常情况&#xff0c;可能会导致程序中断或产生错误结果。常…

uni-app(优医咨询)项目实战 - 第3天

学习目标: 掌握 luch-request 网络请求的用法 能够对 Pinia 进行初始化操作 掌握创建 Store 及数据操作的步骤 能够对 Pinia 数据进行持久化的处理 掌握用户登录的实现方法 一、项目启动 从零起步创建项目,完整的静态页面可以从 gitee 仓库获取。 1.1 创建项目 以 HBuilde…

JavaEE 多线程详细讲解(1)

1.线程是什么 &#xff08;shift F6&#xff09;改类名 1.1.并发编程是什么 &#xff08;1&#xff09;当前的CPU&#xff0c;都是多核心CPU &#xff08;2&#xff09;需要一些特定的编程技巧&#xff0c;把要完成的仍无&#xff0c;拆解成多个部分&#xff0c;并且分别让…

中国打造成熟工艺产能,台积电力推先进工艺,反杀成功了!

分析机构指出2023年Q4全球芯片市场28纳米及以上工艺芯片占比在快速下降&#xff0c;已跌穿五成&#xff0c;这主要是台积电力推芯片企业向先进工艺发展&#xff0c;与中国大陆打造的成熟工艺芯片抗衡。 分析机构指出2023年Q4全球芯片以工艺划分&#xff0c;28纳米及以上工艺的芯…

考研入门55问---基础知识篇

考研入门55问---基础知识篇 01 &#xff1e;什么是研究生入学考试&#xff1f; 研究生是指大专和本科之后的深造课程。以研究生为最高学历, 研究生毕业后&#xff0c;也可称研究生&#xff0c;含义为研究生学历的人。在中国大陆地区&#xff0c;普通民众一般也将硕士毕业生称…

[入门] Unity Shader前置知识(5) —— 向量的运算

在Unity中&#xff0c;向量无处不在&#xff0c;我想很多人都使用过向量类的内置方法 normalized() 吧&#xff0c;我们都知道该方法是将其向量归一化从而作为一个方向与速度相乘&#xff0c;以达到角色朝任一方向移动时速度都相等的效果&#xff0c;但内部具体是如何将该向量进…

Spring - 8 ( 10000 字 Spring 入门级教程 )

一&#xff1a; MyBatis 1.1 引入 MyBatis 我们学习 MySQL 数据库时&#xff0c;已经学习了 JDBC 来操作数据库, 但是 JDBC 操作太复杂了. 我们先来回顾⼀下 JDBC 的操作流程: 创建数据库连接池 DataSource通过 DataSource 获取数据库连接 Connection编写要执行带 ? 占位符…

21岁的人生赚51W!拒绝捞男捞女,翻身也要爱惜身体!——早读(逆天打工人爬取热门微信文章解读)

身体是革命的本钱 引言Python 代码第一篇 卢克文工作室 捞女在今天的中国是怎样的存在第二篇 人民日报 来啦 新闻早班车要闻社会政策 结尾 我将我的健康视为生活的基石 不会为了短暂的成功而牺牲 我珍惜身体 知道健康是实现梦想的前提 引言 这里毕竟是一个程序员的代码学习平台…

LVS/NAT工作模式介绍及配置

1.1 LVS/NAT模式工作原理 LVS&#xff08;Linux Virtual Server&#xff09;的网络地址转换&#xff08;NAT&#xff09;模式是一种在网络层&#xff08;第四层&#xff09;实现负载均衡的方法。在NAT模式中&#xff0c;Director Server&#xff08;DS&#xff09;充当所有服务…

54.HarmonyOS鸿蒙系统 App(ArkTS)tcp socket套接字网络连接收发测试

工程代码https://download.csdn.net/download/txwtech/89258409?spm1001.2014.3001.5501 54.HarmonyOS鸿蒙系统 App(ArkTS)tcp socket套接字网络连接收发测试 import socket from ohos.net.socket; import process from ohos.process; import wifiManager from ohos.wifiMana…

sql 中having和where区别

where 是用于筛选表中满足条件的行&#xff0c;不可以和聚类函数一起使用 having 是用于筛选满足条件的组 &#xff0c;可与聚合函数一起使用 所以having语句中不能使用select中定义的名字

51单片机软件环境安装

keli5的安装 把CID放到破解程序中 破解程序会给一串数字然后填到那个框中 驱动程序的安装 安装完了以后 设备管理器会出现这个 同时c盘会出现这个文件夹

区块链 | IPFS:IPNS(实操版)

&#x1f98a;原文&#xff1a;Publishing IPNS names Publishing IPNS names with Kubo Step1&#xff1a; 启动你的 IPFS 守护进程&#xff08;如果尚未运行&#xff09;&#xff1a; $ ipfs daemon说明&#xff1a;以 $ 开头的是命令&#xff0c;以 > 开头的是执行结果…

php 常见的判断语句和用法

在 PHP 中&#xff0c;常见的判断语句主要使用 if、else、elseif&#xff08;或 else if&#xff09;、switch 和 case。这些语句用于根据条件执行不同的代码块。以下是这些判断语句的详细用法&#xff1a; 1. if 语句 if 语句用于在条件为真时执行代码块。 if (条件) {// 如…

深入探索CSS伪类:解锁样式与交互的无限可能

CSS伪类是CSS中一个强大的特性&#xff0c;它们允许开发者基于元素的状态或位置来应用特定的样式&#xff0c;而无需修改HTML结构。伪类扩展了CSS的选择器语法&#xff0c;使得网页设计更加动态和交互友好。本文将全面介绍几种常用的CSS伪类&#xff0c;配以实用代码示例&#…

算法训练营第十八天 | LeetCode 102 二叉树的层序遍历、LeetCode 226 翻转二叉树、LeetCode 101 对称二叉树

LeetCode 102 二叉树的层序遍历 这题用的队列和指针遍历法。难点在于记录每层末尾位置&#xff0c;这就要用到两个指针&#xff0c;一个end指针记录末尾节点&#xff0c;一个endchild跟着遍历该层内子节点位置&#xff0c;记录下一层末尾节点位置&#xff0c;方便在该层节点遍…

【leetcode】二叉树的构造题目总结

108. 将有序数组转换为二叉搜索树 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), ri…