当前位置: 首页 > news >正文

mysql:B+树/事务

B+树 : 为了数据库量身定做的数据结构

我们当前这里的讨论都是围绕 mysql 的 innodb 这个存储引擎来讨论的

其他存储引擎可能会用到hash 作为索引,此时就只能应对这种精准匹配的情况了

要了解 B+树 我们先了解 B树, B树 是 B+树 的改进

B树 有时候会写作 B-树 (这里的" - "是连接符)

B树 的核心思路和"二叉搜索树"差不多,一个节点上,可以保存多个 key ,N 个 key 就能延伸出 N+1 个分叉来,N 个 key 就划分出了 N+1 个区间(比如四个 key 就有五个分叉,三个 key 就有四个分叉)

B树 如下图所示

B树 查询元素的流程,拿着要查询的元素从根节点出发

比如我们要查询23,先看看23在不在根节点,如果不存在就看看23落在根节点的哪个区间,23<30,所以落在30左边的区间,再看看存不存在,不存在就看看又落在哪个区间,20<23<25,所以落在20~25中间这个区间,然后就在里面找到了23

此时每个节点上都可以保存多个元素,所以说当元素固定的时候,相较于二叉搜索树,涉及到的节点大大减少了,树的高度也大大降低了

B树 的高度是远远小于二叉搜索树的,于是进行查询的时候,硬盘 IO 的次数也就随之减少了(对于数据库来说每个节点都需要把数据从硬盘上读出来才能进行比较,B树 就能一次读取多个数据,每读取一次都是一次 IO,这下一次 IO 读取多个,次数就减少了)

一个节点上有多个 key 和一个节点上有一个key ,硬盘 IO 的开销是差不多的

对于 B树 来说,再进行插入元素和删除元素的时候,涉及到拆分和合并的操作

因为一个节点可以存多个 key,但是也不能无限存,当存储的 key 的数量达到一定程度的时候,就需要把这个节点给拆分,把这个节点中的一部分 key 以树的子节点的方式来进重新组织,这样就会衍生出新的叶子结点,当父节点被删了几个,叶子结点就会填补上

具体啥时候拆分,怎么拆分,具体啥时候合并,怎么合并,就看实际的视线了,不同场景下可以有不同的策略

B+树才是数据库索引的主角.在 B树 的基础上,又进一步地做出了一些改进(针对数据库的查询场景展开的)

1.B+树 也是N叉搜索树,但是N个 key 分出了N个区间,其中节点上的最后一个 key 就是最大值了(取最小值也行)

2.父节点的 key 会在子节点中重复出现(而且是以最大值的身份)

看起来有很多重复元素,但是包含了一个重要信息==>"叶子结点就是整个数据的全集"

3.把叶子节点按照类似于链表这样的方式,首尾相连,此时通过叶子节点之间的连接就可以快速找到"上一个""下一个"元素,也方便进行范围查询,比如我们要找<11的数据,先从根节点开始找,看11最后在叶子节点的哪个位置,然后从11开始到链表最左边的位置就是目标结果

上面三个是 B+树的特点,这些特点产生的优势是什么呢?

1.特别擅长范围查询

2.所有的查询操作,最终都会落到叶子节点上,比较次数是均衡的,查询时间稳定的

有的时候稳定比"快"更重要

3.由于叶子结点上是完整的数据全集,因此表的每一行数据都可以保存在叶子节点上,而非叶子节点值存储构建索引的 key 即可(只存简单的 Id 就行了)

其实在物理层面上不需要"表格"这样的数据结构,直接使用 B+ 树来存储这个表的数据,"表格"只是用户看起来这像是个表格而已

此时非叶子的存储空间消耗是非常小的,可以再内存中缓存一份,此时进行数据查询的时候,就可以通过内存来直接进行比较,从而更快地找到叶子节点上的记录,又进一步减少了键盘 IO 的次数

B树 如果也要把元素存储到每个节点上,非叶子节点就会占据较大的空间,从而无法再内存中缓存了

这里的面试题:介绍对数据库索引的认识,这里就包含该博客介绍的所有内容

事务

事务的基本情况

有的时候为了完成某个工作,需要多组 sql 操作

事务的本质就是为了把多个操作打包成一个操作来完成(让多个操作要么全都执行成功,要么就一个都不执行)

注意一个要点,"一个都不执行"不是真的没执行,执行成不成功得执行了之后才知道,真正执行之前是不知道哪一步会失败的,如果是执行到中间出错了,就需要自动地把前面已经成功执行的操作进行还原,还原回最初没执行的模样(给还原这个操作起了个名字叫做回滚 rollback)

回滚是怎么实现的? 只要把事务中执行的每个操作都记录下来(通过特定的日志),如果需要回滚,就直接按照之前的操作的"逆操作"来执行就可以了(比如插入的逆操作就是删除,删除的逆操作就是插入,修改的逆操作就是修改回去)

下面举个例子

start transaction 开启事务

开启事务后就可以输入多个 sql 语句了

commit 提交事务,把这些 sql 按照原子的方式来进行执行(带有回滚机制)

rollback 手动触发回滚

一个事物务必要以 commit 或者 rollback 这两个操作结尾,如果没有这俩操作,接下来的各种 sql 操作都会被认为是事务的一部分

上述操作不做演示,因为实际开发中往往使用程序代码来操作事务,不太会用命令操作事务 ,代码中操作事务和这几个命令差别较大

事务的基本特性(面试必考):

1.原子性: 保证多个操作被打包成一个整体,要么能够全部执行正确,要么就一个都不执行

2.一致性:事务执行之前和事务执行之后,数据能对得上,数据不能不靠谱

回滚机制不光支持了原子性,还支持了一致性

3.持久性: 事务这里执行的各种操作,都是持久生效的(最终写入硬盘中的),一旦事务执行成功,这里的所有操作产生的修改,都是写到硬盘里的(即使重启服务器,重启主机,它们也不会失效)

4.隔离性: 并发执行事务的时候 ,隔离性会在执行效率和数据可靠之间做出权衡,可以让程序员在使用的时候,根据实际需要来决定我们是要隔离性高一些数据可靠一些,还是要隔离性低一些效率高一些

"隔离"描述的是同时执行的事务之间相互的影响

隔离性越高,并发性就越低,数据越可靠,性能就越低

啥是并发? 简单理解为同时执行.

数据库是一个客户端服务器结构的程序,既然是服务器,服务器就可以同一时刻给多个客户端提供服务,这多个客户端就都能给服务器提交事务,如果提交的两个事务,是修改不同的数据库,修改不同的表,相互之间就没啥影响,但是修改的是同一个表的话,这个时候就可能存在麻烦 

下面举个例子,两个客户端都去修改同一个余额表

假设 客户端1 有两个操作,客户端2 有一个操作,两个客户端的操作必然有先后区别,造成的结果也就会不一样

所以最后的判定到底是根据1000还是3000?这是存在歧义的

这就是并发执行事务所带来的问题

脏读是我们并发执行事务中非常典型也非常常见的问题:

如何解决脏读问题?  给写操作加锁即可,事务A 写的时候,其他事务不能读了,直到事务A 写完数据,提交了事务,其他事务才能读取数据

引入了写加锁,降低了两个事务之间的并发性,提高了隔离性,降低了效率,使数据更准确了

不可重复读是我们并发执行事务中常见的问题:

如何应对不可重复读? 给读操作也加锁,别人读的时候就不能写了, 此时并发程度又进一步降低了,隔离性进一步提高了,执行效率变低了,数据可靠性更高了

解决幻读: 办法只有一个,串行化.彻底放弃并发执行事务,所有的事务都是一个挨一个的串行执行,执行完一个事物,再执行下一个事务,并发性最低,隔离性最高,效率是最低的,数据是最可靠的

Mysql 提供了四种事务的隔离级别

mysql 可以配置自己的隔离级别是哪个,咱们可以根据实际的需求场景来决定使用哪个隔离级别,找到一个效率和可靠性都能接受的情况,但是大部分情况下使用默认的隔离级别就够用了(repeatable read)

相关文章:

mysql:B+树/事务

B树 : 为了数据库量身定做的数据结构 我们当前这里的讨论都是围绕 mysql 的 innodb 这个存储引擎来讨论的 其他存储引擎可能会用到hash 作为索引,此时就只能应对这种精准匹配的情况了 要了解 B树 我们先了解 B树, B树 是 B树 的改进 B树 有时候会写作 B-树 (这里的" -…...

python-在系统托盘显示CPU使用率和内存使用率

一、添加轮子 1.添加托盘区图标库 infi.systray from infi.systray import SysTrayIcon 2.添加图像处理库 Pillow from PIL import Image, ImageDraw, ImageFont 3.添加 psutil 来获取CPU、内存信息 import psutil 二、完整代码 from infi.systray import SysTrayIcon …...

构建mono-repo风格的脚手架库

前段时间阅读了 https://juejin.cn/post/7260144602471776311#heading-25 这篇文章&#xff1b;本文做一个梳理和笔记&#xff1b; 主要聚焦的知识点如下&#xff1a; 如何搭建脚手架工程如何开发调试如何处理命令行参数如何实现用户交互如何拷贝文件夹或文件如何动态生成文件…...

云安全—etcd攻击面

0x00 前言 本篇还是一样&#xff0c;先来说一说etcd是什么&#xff0c;干啥的&#xff0c;然后再来看看etcd的攻击面到底有哪些&#xff0c;做一个抛砖引玉的作用&#xff0c;如有不妥之处还请斧正 0x01 etcd 依旧还是按照问问题的方式来进行阐述&#xff0c;因为学到的东西…...

类锁和实例对象锁你分清了吗?

系列文章目录 文章目录 系列文章目录前言一、什么是锁竞争&#xff1f;二、什么是类锁&#xff1f;什么是实例对象锁&#xff1f;三、给类对象加锁不是锁住了整个类四、总结 前言 java选手们应该都对锁不陌生&#xff0c;加锁了就是为保证操作语句的原子性&#xff0c;如果你是…...

如何在麒麟上安装 ONLYOFFICE 桌面编辑器

我们很高兴地告诉大家&#xff0c;ONLYOFFICE 桌面编辑器现已上架麒麟软件商店。请阅读下文了解详情。 关于麒麟 麒麟是一款国产操作系统&#xff0c;主要是为了满足中国市场的需求和偏好而设计的。 它能够与各种硬件平台和软件应用程序的广泛兼容&#xff0c;因而受到认可。…...

记录:如何编写linux驱动,用module的方式

记录:如何编写Linux驱动,用module的方式 记录:如何编写Linux驱动,用module的方式参考记录:如何编写Linux驱动,用module的方式 编写一个 Linux 的驱动,用 module 方式开发,一般来说,编写一个 Linux 的驱动,需要遵循以下步骤: 确定设备的类型和功能,以及它在系统中的…...

3款免费又好用的 Docker 可视化管理工具

前言 Docker提供了命令行工具&#xff08;Docker CLI&#xff09;来管理Docker容器、镜像、网络和数据卷等Docker组件。我们也可以使用可视化管理工具来更方便地查看和管理Docker容器、镜像、网络和数据卷等Docker组件。今天我们来介绍3款免费且好用的 Docker 可视化管理工具。…...

C语言--判断一个年份是否是闰年(详解)

一.闰年的定义 闰年是指在公历&#xff08;格里高利历&#xff09;中&#xff0c;年份可以被4整除但不能被100整除的年份&#xff0c;或者可以被400整除的年份。简单来说&#xff0c;闰年是一个比平年多出一天的年份&#xff0c;即2月有29天。闰年的目的是校准公历与地球公转周…...

Python---排序算法

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 Python中的排序算法用于对数据进行排序。排序算法可以使数据按照一定的规则进行排列&#xff0c;以便于数据的查找、统计、比较等操作。在数据分析、机器学习、图形计算等领域&#xff0c…...

gitlab Blocking and unblocking users

原文&#xff1a;Redirecting... Blocking a userUnblocking a user Blocking and unblocking users GitLab 管理员阻止和取消阻止用户. Blocking a user 为了完全阻止用户访问 GitLab 实例&#xff0c;管理员可以选择阻止该用户. 可以通过滥用报告或直接从管理区域来阻止…...

Swift 和 Python 两种语言中带关联信息错误(异常)类型的比较

0. 概览 如果我们分别在平静如水、和谐感人的 Swift 和 Python 社区抛出诸如“Python 是天下最好的语言…” 和 “Swift 是宇宙第一语言…”之类的言论会有怎样的“下场”&#xff1f; 我们并不想对可能发生的“炸裂”景象做出什么预测&#xff0c;也无意比较 Swift 与 Pytho…...

北京联通iptv组播配置

多年前折腾过iptv&#xff0c;近期搬家换了个大电视&#xff0c;打算把iptv配置好了&#xff0c;尽管不怎么看&#xff0c;但聊胜于无。 其实很简单&#xff0c;用到了一些工具&#xff0c;记录如下 1. openwrt配置 因为有软路由&#xff0c;所以就借助openwrt了&#xff0c;一…...

C++ STL 迭代器失效

一、学习资料 STL迭代器的使用 二、vector容器获取值是下标法和at()的区别 vector<int> vA; int array[]{0,1,2,3,4}; vA.assign(array,array5); cout<<vA[6]<<endl; cout<<va.at(6)<<endl;如上述代码&#xff0c;当使用vA[6]的方式出现访问越…...

麒麟KYLINIOS软件仓库搭建02-软件仓库添加新的软件包

原文链接&#xff1a;麒麟KYLINIOS软件仓库搭建02-软件仓库添加新的软件包 hello&#xff0c;大家好啊&#xff0c;今天给大家带来麒麟桌面操作系统软件仓库搭建的文章02-软件仓库添加新的软件包&#xff0c;本篇文章主要给大家介绍了如何在麒麟桌面操作系统2203-x86版本上&…...

专业媒体播放软件Movist Pro中文

Movist Pro是一款专为Mac用户设计的专业媒体播放器。它支持广泛的视频和音频格式&#xff0c;包括MP4、AVI、MKV等&#xff0c;并提供了高级播放控件和定制的视频设置。其直观易用的用户界面&#xff0c;使得播放高清视频更为流畅&#xff0c;且不会卡顿或滞后。同时&#xff0…...

数据结构-邻接表广度优先搜索(C语言版)

对于一个有向图无向图&#xff0c;我们下面介绍第二种遍历方式。 广度优先搜索&#xff0c;即优先对同一层的顶点进行遍历。 如下图所示&#xff1a; 该例子&#xff0c;我们有六个顶点&#xff0c; 十条边。 对于广度优先搜索&#xff0c;我们先搜索a&#xff0c;再搜索abc…...

Py之auto-gptq:auto-gptq的简介、安装、使用方法之详细攻略

Py之auto-gptq&#xff1a;auto-gptq的简介、安装、使用方法之详细攻略 目录 auto-gptq的简介 1、版本更新历史 2、性能对比 推理速度 困惑度&#xff08;PPL&#xff09; 3、支持的模型 3、支持的评估任务 auto-gptq的安装 auto-gptq的使用方法 1、基础用法 (1)、量…...

【Linux】Linux+Nginx部署项目(负载均衡动静分离)

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于Linux的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.Nginx负载均衡 1.什么是负载均衡 2.实…...

C++笔记之vector的成员函数swap()和data()

C笔记之vector的成员函数swap()和data() 标准C中的std::vector类确实有swap()和data()这两个成员函数。下面是它们的简要描述&#xff1a; swap(): std::vector的swap()成员函数用于交换两个向量的内容&#xff0c;实现了高效的交换操作&#xff0c;不需要复制向量的元素。这…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...