MySql(面试题理解B+树原理 实操加大白话)

数据的定位

通过磁道和扇区定位到数据的位置

扇区为512字节

黄色地方数据位置为2磁道3扇区

黑色地方数据位置为1磁道1扇区 

 通过磁道和扇区还有偏移量定位到数据的位置

 比如这里有一张表

17b94050505f4fada5323f71841e0dc4.png

由id、name、no、address组成id为主键
列占有大小(字节)
id int 8
name varchar 40
no int 8
address varchar 72

e411391205284fcda42984e44d9557b7.png

 一条记录就占了128个字节。

我们数据有1000条 1000 * 128 = 128,000B

那么是多少扇区呢? 128,000 / 512 = 250 个扇区

意味着我们把1000条数据存入需要250个扇区

如果数据没有索引就要全表扫描,最大读取次数就是250次IO非常慢。

这个时候就有了索引表

e892b637829442cc9a9f7e271ec983c9.png

索引包括了主键的ID和数据表每个记录的地址。

地址可以通过int 表示。

09845781dd254ae4a33f4f693982434d.png

索引项大小就是8 + 8 = 16B

索引也要存在磁盘上 1000 * 16 = 16000B 

16000 / 512 约等于 31个扇区 意味着我们要拿31个扇区存储该索引。

这个时候我们有了索引就是走索引最坏情况就是全部扫了一遍最多31个扇区。

从之前的250个扇区到31个扇区加快了读写效率。

31(获得索引条目) + 1(转到特定块) = 32 个扇区

我们可以在索引上套索引不知道大家是否学习过二级页表。

 二级索引可以覆盖一定范围比如id为1在二级索引包含一级索引的id1到id10

100 * 16 = 1600 1600 / 512 约等于4个扇区

那么这个范围一定是10吗?

一个扇区512字节,一个一级索引表项为16字节,512 / 16 = 32 个

意味着一个二级索引表项可以取到32个一级索引表项 

一级索引有1000个索引表项 1000 / 32 约等于 31

那就说明二级索引只要有31个索引项就行

31 * 16 = 496 连一个扇区都没装满 只需要一次IO 就可以读取所有

一级索引二级索引都要保存在磁盘上

最后二级索引就变成这样了 

那么访问过程是怎样的呢

比如id等于2的时候先一次查找二级索引(IO一次),通过二级索引找到一级索引(IO两次),一级索引里面有0到32范围可以通过二分查找到id等于2的索引,再通过一级索引找到数据(IO三次)

muitl-way search tree - 多路搜索树

B树与B+树详解:磁盘结构、索引优化与搜索树深入解析

原文在这我顺几张图懒得画了(bushi

  1. 每个节点最多有3个子节点
  2. 每个节点有2个key关键字

 多路搜索树的问题

10 - way search tree

10 key(元素) 9 children(分支)

 10 20 30 40 50

这个树就会一直这样连续下去因为没有规则的限制就没有任何意义。

因此B树产生了 比如每个非根节点至少要有m/2向上取整个子节点

B树基础

f800627c4e4b428196da04a0dd6c5fe7.png

B树特性

2d49808533514fbeacf6a285957a586e.png

B树查找数据  

fb25c19ad43440e99886753f51e8f6d8.png

ef2abc5307df43bcb2d8e47a4d78a7c2.png

磁盘不会一次性把树都读入内存,而是用到则读。上图进行了三次磁盘的IO。可见树高和磁盘读写是正相关

B树插入

下图是三阶B树最多元素个数为 3(m) - 1 = 2

假如一个节点为3个元素 需要 3(m)/2 向上取整 = 2 把第二个元素上移分裂左右。

7288d8bbd56c404ba27868b072228635.png

B树构建

daffd91c7e964632a3bb651798d13baf.png

B+树介绍

d83e56335b52420ab942523bc2c93314.png

fe8982ffda9d4f18b98221e792719d1b.png

B树和B+树区别

21940ad9e26a4cf39959431e32ac4112.png

随机查找B+树 

9efa1a8b73fb429b8fa5f4a8f73fccde.png

范围查找B+树

6c4d5faab822415eb7d7307f96d6bccf.png

结合mysql数据库理解

操作系统连续读和缓存数据的原理,当一个数据被用到的时候它附近的数据也会被用到。磁盘每一次发生读操作的时候,在找到目标数据之后都会连续读取4 KB的数据。文件系统把一个块的大小定义成了4KB,每次IO操作加载8个扇区的数据到内存中。而MySQL认为4KB太小了,Mysql中最小存储单元是页(16KB),每次IO操作都可以缓存16KB的数据,会把16KB数据放到Buffer Pool中没有ByteBuffer的大小恰好是16KB。

即使32行数据不创建索引 ,在查找数据未必感觉会慢,这个就是顺序读和BufferPool带来的便利,数据太大的时候几百万的时候就不得不创建索引了,在mysql中所有数据都是存储在page里面的。

mysql中统计数据的占用空间用page计算

一个Page(16KB)/一条记录(512B) = 32条记录

SSD一次IO读4KB块读取32条记录需要读4次

 假如将ID这列创建索引,索引也要占空间。

假设指令为6B key就是ID

一个Page(16KB)/(key(8B)+指针(6B) = 1170 条索引

 1170 * 32 = 37,440条数据

1170 * 1170 * 32 = 43,804,800 条数据

以空间换时间

B+树到底可以存储多少数据呢

在Innodb存储引擎里面,最小存储单元是页,而一个页的大小默认是16KB。

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

非叶子节点存放的是主键值与指针,所以这里假设主键类型为bigint,占用8Byte,指针可以设置为占用6Byte,总共就为14Byte,这样就可以算出一个节点大概可以存放多少个指针了(指针指向下一层节点),大概为16KB/14Byte=1170个。 这里之前算过了

由此,可以推算出,2层B+树的话,可以存放1170*16=18720行数据。3层B+树的话,可以存放1170*1170*16=21902400行数据,也就差不多2000w条数据了。4层B+树的话1170*1170*1170*16,5层B+树 1170 * 1170 * 1170 * 1170 * 16

总结

遍历时候,顺序扫描叶子结点比中序遍历整棵树要快。

B+树的作用是一次IO可以检索更多的数据。 因为树节点中不必存储自己的数据,数据全部存储在叶子节点。树节点的存储数据更小,磁盘一次io能将更多的树节点中的数据读入到内存中,加快检索的效率。

B+树与B树的设计主要用于提高​IO速度,也就是读取磁盘的速度。无论是记录查询还是索引查询主要受限于硬盘的I/O速度,查询I/O次数越少,速度越快,所以就产生了B树。B树中每个节点都可以存放表的行记录数据,每个节点的读取可以视为一次I/O读取,树的高度表示最多的I/O次数,在相同数量的总记录个数下,每个节点的记录个数越多,高度越低,查询所需的I/O次数越少.

为了进一步提高磁盘的访问效率,就产生了B+树,B+树与B树最大的不同是内部结点不保存记录数据,只保存关键字,用于查找,所有记录数据都保存在叶子结点中。由于每个非叶子节点只存放关键字,这样节点中能存放的关键字数量就更多,每个节点的扇出数就越大,树的结构就更加矮小,访问磁盘的次数就更少。

基本上是个人理解加参考其他大佬的肯定有很多问题欢迎指正,我会及时修改。

参考文献

1. mysql面试题-深入理解B+树原理_哔哩哔哩_bilibili

B树(B-树) - 来由, 定义, 插入, 构建_哔哩哔哩_bilibili

数据结构合集 - B+树_哔哩哔哩_bilibili

头条面试:请描述MySQL的B+树索引原理,B+树索引有哪些好处_哔哩哔哩_bilibili

B树与B+树详解:磁盘结构、索引优化与搜索树深入解析

彻底理解B树和B+树!为何它们常用在数据库中?_哔哩哔哩_bilibili

面试官问我为啥B+树一般都不超过3层?3层B+树能存多少数据?redo log与binlog的两阶段提交?_b+树为什么三层-CSDN博客

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

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

相关文章

目标检测,图像分割,超分辨率重建

目标检测和图像分割 目标检测和图像分割是计算机视觉中的两个不同任务,它们的输出形式也有所不同。下面我将分别介绍这两个任务的输出。图像分割又可以分为:语义分割、实例分割、全景分割。 语义分割(Semantic Segmentation)&…

K8s内存溢出问题剖析:排查与解决方案

文章目录 一、背景二、排查方案:1. 可能是数据量超出了限制的大小,检查数据目录大小2. 查看是否是内存溢出2.1 排查数据量(查看数据目录大小是否超过limit限制)2.2 查看pod详情发现问题 三、解决过程 一、背景 做redis压测过程中…

python3 + selenium 中用PIL获取全屏幕截图

获取当前屏幕截图非常简单,需要import PIL.ImageGrab。调用grab函数即可得到Image对象,显示图片如图所示。 高版本的PIL中的grab函数还提供有一些参数。要查看当前PIL包的版本,可以import然后查看其__version__属性。 如果是较高版本的PIL…

请求(request)

目录 前言 request概述 request的使用 获取前端传递的数据 实例 请求转发 特点 语法 实例 实例1 实例2 【关联实例1】 域对象 组成 作用范围: 生命周期: 使用场景: 使用步骤 存储数据对象 获得数据对象 移除域中的键值…

离线安装 Docker-IO:详细步骤指南

离线安装 Docker-IO:详细步骤指南 一、准备工作1.1 下载 Docker 离线安装包1.2 准备安装环境1.3 配置防火墙和 SELinux(可选)二、上传和解压离线安装包2.1 上传安装包2.2 解压安装包三、安装 Docker-IO3.1 移动 Docker 文件到系统目录3.2 配置 Docker 服务3.3 赋予服务文件执…

python图像彩色数字化

效果展示&#xff1a; 目录结构&#xff1a; alphabets.py GENERAL {"simple": "%#*-:. ","complex": "$B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_~<>i!lI;:,\"^. " } # Full list could be found here…

宠物空气净化器推荐2024超详细测评 希喂VS霍尼韦尔谁能胜出

最近有粉丝一直在评论区和后台探讨宠物空气净化器是不是智商税的问题&#xff0c;有人认为宠物空气净化器肯定不是智商税&#xff0c;有些人认为将其购回家就是个没用的东西&#xff0c;还占地方&#xff0c;双方各有自己的观点。 其实宠物空气净化器和普通的空气净化器是有很大…

屏幕分辨率|尺寸|颜色深度指纹

一、前端通过window.screen接口获取屏幕分辨率 尺寸 颜色深度&#xff0c;横屏竖屏信息。 二、window.screen c接口实现&#xff1a; 1、third_party\blink\renderer\core\frame\screen.idl // https://drafts.csswg.org/cssom-view/#the-screen-interface[ExposedWindow ] …

3mf 格式详解,javascript加载导出3mf文件示例

3MF 格式详解 3MF&#xff08;3D Manufacturing Format&#xff09;是一种开放标准的文件格式&#xff0c;专门用于三维制造和打印。3MF 格式旨在解决 STL 格式的局限性&#xff0c;提供更丰富和灵活的数据表示。3MF 文件是一种 ZIP 文件&#xff0c;其中包含了描述三维模型的…

[OS] A4-前菜介绍

从你的描述来看&#xff0c;这段话是给你的一些 预备知识 和 mkfs工具的使用 提示&#xff0c;帮助你了解如何构建和管理文件系统&#xff0c;特别是关于 xv6 文件系统的一些基本操作。 我会通过比喻和通俗化的方式逐步解释&#xff1a; 预备知识&#xff1a;xv6 文件系统的基…

Android 14之HIDL转AIDL通信

Android 14之HIDL转AIDL通信 1、interface接口1.1 接口变更1.2 生成hidl2aidl工具1.3 执行hidl2aidl指令1.4 修改aidl的Android.bp文件1.5 创建路径1.6 拷贝生成的aidl到1和current1.7 更新与冻结版本1.8 编译模块接口 2、服务端代码适配hal代码修改2.1 修改Android.bp的hidl依…

数据结构代码合集

一、排序算法 1、插入排序 1.1 直接插入排序 void InsertSort(int A[],int n){int temp,i,j; for( i 1;i<n;i){ //外循环&#xff0c;每个元素都要进行排序 if(A[i-1]>A[i]){ //前面元素比后面元素大的话 temp A[i];for( j i-1; A[j]>temp && j>0…

《硬件架构的艺术》笔记(九):电磁兼容性能设计指南

简介 电子线路易于接收来自其他发射器的辐射信号&#xff0c;这些EMI&#xff08;电磁干扰&#xff09;使得设备内毗邻的元件不能同时工作。这就有必要进行电磁兼容设计以避免系统内有害的电磁干扰。 确保设备不产生多余的辐射&#xff0c;设备也不易受到射频辐射的干扰&…

Anaconda安装(2024最新版)

安装新的anaconda需要卸载干净上一个版本的anaconda&#xff0c;不然可能会在新版本安装过程或者后续使用过程中出错&#xff0c;完全卸载干净anaconda的方法&#xff0c;可以参考我的博客&#xff01; 第一步&#xff1a;下载anaconda安装包 官网&#xff1a;Anaconda | The O…

【SpringBoot问题】IDEA中用Service窗口展示所有服务及端口的办法

1、调出Service窗口 打开View→Tool Windows→Service&#xff0c;即可显示。 2、正常情况应该已经出现SpringBoot&#xff0c;如下图请继续第三步 3、配置Service窗口的项目启动类型。微服务一般是Springboot类型。所以这里需要选择一下。 点击最后一个号&#xff0c;点击Ru…

力扣,88. 合并两个有序数组

我的思路是先单独对 数组2 做快排&#xff0c;但是快排的最差性能是 o(n^2) &#xff0c; 题目要求性能是 o( mn) 。 哦哦&#xff0c;不对不对&#xff0c; 它这数组给的就是有序的了&#xff1f; 麻蛋&#xff0c; 不需要排序了。 那就是 一开始最简单的思路&#xff0c; 直接…

Jmeter测试工具的安装和使用,mac版本,jmeter版本5.2.1

Jmeter测试工具的安装和使用JSON格式请求 一、安装1、安装jdk包和设置java环境2、去官网下载Jmeter3、解压后&#xff0c;打开mac终端&#xff0c;进入apache-jmeter的bin文件开启jmeter 二、使用jmeter1、添加线程2、添加HTTP请求3、配置请求的协议、IP地址、端口号、请求方法…

Cookie跨域

跨域&#xff1a;跨域名&#xff08;IP&#xff09; 跨域的目的是共享Cookie。 session操作http协议&#xff0c;每次既要request&#xff0c;也要response&#xff0c;cookie在创建的时候会产生一个字符串然后随着response返回。 全网站的各个页面都会带着登陆的时候的cookie …

多项式加法运算的链表实现

多项式加法运算的链表实现 主要思路&#xff1a;相同指数的项系数相加&#xff0c;其余部分进行拷贝。 两个多项式分别使用单链表实现&#xff0c;链表的每一个节点的结构为&#xff1a;系数、指数、下一个节点的地址。 链表节点按照指数递减顺序排列。 一句话&#xff1a;…

【N 卡 掉驱动 Driver 】NVML ERROR: Driver Not Loaded

问题描述 输入 nvitop 时报错 NVML ERROR: Driver Not Loaded&#xff0c;重启问题依旧存在。 问题解决-重新下载驱动 进入官网选择合适自己的驱动版本 https://www.nvidia.cn/geforce/drivers/ 根据个人情况搜索后&#xff0c;选择最新的 Driver 进行下载&#xff0c;如果希…