MySQL-事务、日志

事务

特性

原子性

是指事务开始后,必须成功执行完所有的操作才会结束,否则会回滚到事务刚开始前。

拿转账来说,一个成功的 A向B转账100元的过程 会涉及如下过程:

A:从数据库读取A的余额;A的余额-100;将A修改后的余额更新到数据库里

B:从数据库读取B的余额;B的余额+100;将B修改后的余额更新到数据库里

 若这个步骤任何一个没有执行成功,A向B转账100就无法成功,A的余额与B的余额都不会变化。

一致性

是指事务操作前后,数据库保持一致状态。

比如,用户A和用户B的账户分别有800元和600元,总共1400,用户A向用户B转账100元,分为两个步骤,从A账户扣除100元,B账户增加100元。一致性要求转账操作完成后,两个人账户总额依然是1400。

拿 A向B转账100元来说,执行完后,A的余额会减100,B的余额会加100,不会出现A的余额不变化等错误。

持久性

事务的改变是持久的,事务处理结束后,对数据的修改时永久的,即便系统故障也不会丢失。

隔离性

数据库允许多个并发事务同时对其数据进行读写和修改,隔离性很好的防止了多个事务并发执行而导致数据不一致的情况。每个事务都有一个完整的数据空间,对其他并发事务是隔离的,不会相互干扰;一个事务对另一个事务是否可见以及可见的程度。

购买商品来举例,消费者购买商品这个事务,是不影响其他消费者购买的。

并行事务回引发哪些问题

脏读

如果一个 事务 读到 另一个未提交事务 修改过的数据,就意味着发生脏读现象。

举例:如果一个B事务读到了另一个 未提交的A事务 修改过的数据,会发生脏读现象,因为A事务还未提交,随时可能发生回滚操作,那么B事务刚才读到的数据就是过期的数据。

不可重复读:

一个事务内多次读取同一个数据,会出现前后两次读到的数据不一样的情况,就意味着发生了不可重复读现象。

举例:事务A从数据库中读取余额,读到的数据是100,然后继续执行代码逻辑,此时,B更新了余额(设置余额为200),并提交了事务,那么当A事务再次读取数据时,就会发现前后两次读到的数据不一致,这种现象被称为不可重复读。

幻读

在一个事务内,多次查询某个符合查询条件的记录数量,如果出现前后两次查询的记录数量不一样的情况,就意味着发生了幻读现象。

举例:事务B在查询账户余额大于100元的账户数量,查询到5条记录,接下来,事务A插入了一条余额超过100元的账户,并提交了事务,此时数据库超过100的账户数量为6,然后B事务再次查询账户余额大于100元的记录,此时查到的记录数量为6,发现和前一次读到的记录数量不一样,就感觉发生了幻觉,这种现象被称为幻读。

事务隔离

当多个事务并发执行肯可能会遇到脏读、不可重复读、幻读现象,如何规避呢?

  • 脏读:B事务读到了A事务修改后未提交的数据
  • 不可重复读:同一个事务内,前后读取的数据不一致
  • 幻读:事务读取数据库中的前后记录数量不一样

解决脏读              :用读已提交、可重复读、串行化;

解决不可重复读   :用可重复读、串行化

解决幻读              :用串行化

四种隔离级别读未提交、串行化、读已提交、可重复读

四种隔离级别是如何实现的

读未提交

定义:指一个事务还没提交时,它做的变更就被其他事务看到;

实现:因为可以读到未提交事务的修改,所以直接读取最新的数据;

可能发生"脏读、不可重复读、幻读"问题:
  • 脏读:B事务读到了A事务修改后未提交的数据
  • 不可重复读:同一个事务内,前后读取的数据不一致
  • 幻读:事务读取数据库中的前后记录数量不一样
产生问题举例——读未提交产生脏读

上图中,事务A与事务B开启后,事务B将name改为“关羽”,事务未提交,但是如果事务A读到了name为“关羽”,而sessionB未提交随时可能发生回滚,那么事务A相当于读到了一个不存在的数据,即脏读。读到了一条数据。

串行化

定义:会对事务加上读写锁,在多个事务对这条记录进行读写操作时,如果发生了读写冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行;

实现:通过加读写锁的方式来避免并行访问;

读已提交

定义:指一个事务提交后,它做的变更才能被其他事务看到;

实现:通过Read View实现,是在每个语句执行前都会重新生成Read View;同一个事务中两次相同的读取操作可能会看到不同的数据,因为其他事务可能在两次读取之间提交了数据。

过程:

  1. 去找除本身事务之外的其他活跃的事务ID(read view)
  2. 遍历undo log

 Read View:

确定哪些版本的数据对当前事务可见,维护了除本身事务之外的其他活跃的事务ID,看到的是未提交(活跃)的事务;

  • 事务ID列表:包括了在创建 read view 时,所有未提交的事务ID
  • 最小事务ID:在创建 read view 时,系统中已经提交的最小事务ID。这个ID之前的所有事务的修改对当前事务都是可见的。
  • 当前事务ID:创建 read view 的事务的ID。
可能发生不可重复读和幻读的问题:
  • 不可重复读:同一个事务内,前后读取的数据不一致
  • 幻读:事务读取数据库中的前后记录数量不一样
 产生问题举例——读已提交产生不可重复读

在图,SessionA启动后,Session第一次读到name值是“刘备”;SesssionB自动启动后,修改name为“关羽”,并自动提交了事务,SessionA第二次读到name值是“关羽”,两次读到的数据不一样,发生了不可重复读;SessionB再次更新name,为“张飞”,并自动提交了事务,SessionA第三次读到的name值为“张飞”,对于同一个name,SessionA三次读到的值都不一样,发生了不可重复读问题。

 产生问题举例——读已提交产生幻读

 在图中,SessionA启动后,查到了name为“刘备”的记录,之后SessionB插入了name为“曹操”的记录,并自动提交了事务,session再次查找记录,在与第一次相同的条件(number>0)下,读到了name为“刘备”和“曹操”两条记录。

可重复读

定义:指一个事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的;

实现:启动事务时生成一个Read View,然后整个事务期间都在用这个Read View,之后读取操作都会使用这个read view,保证了在同一个事务中多次读取同一数据时,看到相同的数据版本。

过程:

  1. 去找除本身事务之外的其他活跃的事务ID(read view)
  2. 遍历undo log

 Read View

确定哪些版本的数据对当前事务可见,维护了除本身事务之外的其他活跃的事务ID,看到的是未提交(活跃)的事务;

  • 事务ID列表:包括了在创建 read view 时,所有未提交的事务ID
  • 最小事务ID:在创建 read view 时,系统中已经提交的最小事务ID。这个ID之前的所有事务的修改对当前事务都是可见的。
  • 当前事务ID:创建 read view 的事务的ID。
可能发生“幻读”问题:
  • 幻读:事务读取数据库中的前后记录数量不一样
 Read View

确定哪些版本的数据对当前事务可见,维护了除本身事务之外的其他活跃的事务ID,看到的是未提交(活跃)的事务;

  • 事务ID列表:包括了在创建 read view 时,所有未提交的事务ID
  • 最小事务ID:在创建 read view 时,系统中已经提交的最小事务ID。这个ID之前的所有事务的修改对当前事务都是可见的。
  • 当前事务ID:创建 read view 的事务的ID。
可重复读与已提交的工作过程
  1. 去找除本身事务之外的其他活跃的事务ID(read view)
  2. 遍历undo log

举例

读已提交:每次都重复找

可重复读:延用第一次的

 日志

undo log回滚日志

是innodb存储引擎层生成的日志,实现了事务的原子性,主要用于事务回滚;记录了数据被修改之前的状态,以便在事务回滚或者需要读取旧版本数据时能够恢复到之前的状态;发生回滚时,就读取undo log里的数据,然后做原先相反的操作。

每次操作产生的undo log格式都有roll_pointer指针可以将这些undo log串成一个链表,trx_id知道该记录时被哪个事务修改的。

 插入操作:在插入一条记录时,把这条记录的主键值记到undo log中,这样回滚时只需把这个主键值对应的记录删掉就好。

删除操作:删除一条记录时,要把记录中的内容对记到undo log中,回滚时把由这些内容组成的记录(通过roll_pointer找到之前版本中delete_mask为0的记录)插入到表中就好。

更新操作:在更新一条记录时,把更新列的旧值记到undo log中,回滚时把这些列的更新为旧值(通过roll_pointer找到上一个版本的数据(旧值)就好了。每次修改时,都会生成一个新的undo log记录,并且这个指针会通过roll_pointer指针与之前的undo log记录相连,形成一个版本链,通过roll_pointer找到上一个版本的数据。

redo log重做日志:是innodb存储引擎层生成的日志,实现了事务的持久性,主要用于解决掉电等故障恢复;

binlong归档日志:是server层生成的日志,主要用于数据备份和主从复制

索引的类别

按照实现的数据结构区分

B+树索引

Hash索引

为什么不采用Hash/HashMap这种存储结构而选择B+树呢?

B+树支持按顺序存储和范围查询,而hash结构不支持范围查询,因为Hash是基于Hash函数计算的无序存储结构;B+树的内部节点和叶子节点形成有序链表,这使得在执行顺序访问时非常高效,Hash机构没有内在顺序,无法提供顺序访问性能。

按照约束区分

普通索引

唯一索引(UNIQUE修饰)

MySQL在进行插入操作时,普通索引和唯一索引哪个的效率高?

普通索引更快,因为它不需要唯一性检查。普同索引允许索引键值重复,而唯一索引不允许重复,用唯一索引插入时会检查索引键值是否重复,不重复才插入,若重复则失败。

MySQL在进行查找操作时,普通索引和唯一索引哪个的效率高?

唯一索引更快,保证数据唯一性使得查找的时候索引通过键就能定位符合条件数据行,而普通索引的索引键存在重复,会定位多个数据行,接下来还要遍历数据才能查找到符合条件的数据行。

按照索引列的数量区分

单列索引

联合索引(最左匹配原则)

最左匹配原则是按什么顺序实现的?

从小到大的顺序,如按第一列从小到大的顺序排列,若出现相同的数值,则比较相同数值的下一列,依然是按照从小到大的顺序,后面同理。

联合索引为什么要满足最左匹配原则?

如(A,B,C),从A字段开始匹配才能保证索引的有序性。对于查询,如果跳过A字段直接查询B或C字段,那么这些字段在索引中可能是无序的,从而加速查询过程。

按照存储的内容区分

聚簇索引:B+树的叶子结点存放的是实际数据,索引就是数据,以主键为索引;

非聚簇索引:B+书的叶子结点存放主键值,存储了索引列与主键,除主键外的其他字段为索引;通过非聚簇索引找到了符合条件的数据行,根据存储在索引中的主键,再去访问实际的数据行,这个过程被称为“回表”。

回表:需要检索两颗B+树,先在二级索引的B+树找到对应的叶子结点,获取主键值,然后用获取的主键值在聚簇索引中的B+树检索到对应的叶子结点,然后获取要查询的数据;

索引注意事项

1.ORDER BY子句里使用索引列,但是order by后字段的排序不一致(增减性相反索引失效)就不能使用;

2.为用于搜索、排序或分组的列创建索引;

3.列的区分度大的列创建索引,重复数据多的字段不应设为索引

4.联合索引,区分度大的放在第一位

5.只有索引列在比较表达式中单独出现才可以适用索引

6.为了尽可能少的让聚簇索引发生 页面分裂和记录移位的情况,建议让主键拥有AUTO_INCREMENT属性,让主键自增,防止页分裂(会使插入速度变慢)。

7.尽量使用覆盖索引进行查询,避免回表带来的性能损耗

8.使用IN查询,IN的数量不能太大(<=2000,若大于,则全表扫描就可以),避免mysql走错索引

9.更新频繁的列不应设置索引(索引也需要维护)

索引失效
  • 当我们使用左或者左右模糊匹配的时候,也就是 like %xx 或者 like %xx%这两种方式都会造成索引失效;
  • 当我们在查询条件中对索引列使用函数,就会导致索引失效。
  • 当我们在查询条件中对索引列进行表达式计算,也是无法走索引的。
  • MySQL 在遇到字符串和数字比较的时候,会自动把字符串转为数字,然后再进行比较。如果字符串是索引列,而条件语句中的输入参数是数字的话,那么索引列会发生隐式类型转换,由于隐式类型转换是通过 CAST 函数实现的,等同于对索引列使用了函数,所以就会导致索引失效。
  • 联合索引要能正确使用需要遵循最左匹配原则,也就是按照最左优先的方式进行索引的匹配,否则就会导致索引失效。
  • 在 WHERE 子句中,如果在 OR 前的条件列是索引列,而在 OR 后的条件列不是索引列,那么索引会失效。

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

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

相关文章

QT小细节

QT小细节 1 QTextToSpeech1.1 cmake1.2 qmake QT6 6.7.2 1 QTextToSpeech 从下图可以看到&#xff0c;分别使用qmake或者cmake编译情况下的&#xff0c;QTextToSpeech的使用方法 QTextToSpeech官方链接&#xff0c;也可以直接在QT Creator的帮助中搜索 1.1 cmake 将上图中的…

ArkUI组件——循环控制/List

循环控制 class Item{name: stringprice:number}private items:Array<Item> [new Item("A0",2399),new Item("BE",1999),new Item("Ro",2799)] ForEach(this.items,(item:Item) > {})List组件 列表List是一种复杂的容器&#xff0c;…

微信小程序新建项目发现导航条不见了,及如何找回。

原因是现在小程序新建用的是 Skyline 渲染引擎 开启全局Skyline渲染引擎&#xff0c;因为Skyline不支持原生导航栏&#xff0c;所以就没显示原生导航栏了。 解决方法也很简单 app.json文件中的 “renderer”: “skyline”, 修改为 “renderer”:“webview”app.json文件中的…

CSS基础学习之元素定位(6)

目录 1、定位类型 2、取值 2.1、static 2.2、relative 2.3、absolute 2.4、fixed 2.5、stickty 3、示例 3.1、相对定位(relative) 3.2、绝对定位&#xff08;absolute&#xff09; 3.3、固定定位&#xff08;fixed&#xff09; 3.4、粘性定位&#xff08;sticky&…

大模型中的MoE是什么?

大模型中的MoE是什么&#xff1f; MoE&#xff08;Mixture of Experts&#xff09;是一种用于提高深度学习模型性能和效率的架构。其核心思想是通过引入多个专家&#xff08;Experts&#xff09;模型&#xff0c;每个输入数据只选择和激活其中的一部分专家模型来进行处理&…

nacos 适配瀚高数据库、ARM 架构

下载nacos源码&#xff1a; https://github.com/alibaba/nacos/tree/2.3.1 瀚高技术文档 1、修改pom.xml 根目录nacos-all > pom.xml<dependencyManagement><dependency><groupId>com.highgo</groupId><artifactId>HgdbJdbc</artifactI…

硅纪元视角 | 微软开发全新AI模型,革新电子表格处理效率!

在数字化浪潮的推动下&#xff0c;人工智能&#xff08;AI&#xff09;正成为塑造未来的关键力量。硅纪元视角栏目紧跟AI科技的最新发展&#xff0c;捕捉行业动态&#xff1b;提供深入的新闻解读&#xff0c;助您洞悉技术背后的逻辑&#xff1b;汇聚行业专家的见解&#xff0c;…

使用llama-cpp-python制作api接口

文章目录 概要整体操作流程技术细节小结 概要 使用llama-cpp-python制作api接口&#xff0c;可以接入gradio当中&#xff0c;参考上一节。 llama-cpp-python的github网址 整体操作流程 下载llama-cpp-python。首先判断自己是在CPU的环境下还是GPU的环境下。以下操作均在魔搭…

【Linux杂货铺】期末总结篇4:shell编程

&#x1f308;个人主页&#xff1a;聆风吟_ &#x1f525;系列专栏&#xff1a;Linux实践室、网络奇遇记 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 一. ⛳️什么是Shell脚本&#xff1f;二. ⛳️Shell 入门三. ⛳️Shell 变量3.1 &#x1f514;变…

Kotlin中Unit、Any和Nothing

Unit Unit是一个特殊的类型&#xff0c;它表示“没有意义的值”的单元类型。在Kotlin中&#xff0c;当你不需要函数返回任何具体值时&#xff0c;可以使用Unit类型。 和Java 中 void一样。 Any 所有非空类的父类 Any?所有类的父类 类似Java中Object Nothing 表示一个函数或…

旗晟巡检机器人的应用场景有哪些?

巡检机器人作为现代科技的杰出成果&#xff0c;已广泛应用于各个关键场景。从危险的工业现场到至关重要的基础设施&#xff0c;它们的身影无处不在。它们以精准、高效、不知疲倦的特性&#xff0c;担当起保障生产、守护安全的重任&#xff0c;为行业发展注入新的活力。那么&…

如何使用简鹿水印助手或 Photoshop 给照片添加文字

在社交媒体中&#xff0c;为照片添加个性化的文字已经成为了一种流行趋势。无论是添加注释、引用名言还是表达情感&#xff0c;文字都能够为图片增添额外的意义和风格。本篇文章将使用“简鹿水印助手”和“Adobe Photoshop”这两种工具给照片添加文字的详细步骤。 使用简鹿水印…

IDEA实现NPM项目的自打包自发布自部署

目录 前言 正文 操作背景 NPM自发布 Package自发布 NPM部署 尾声 &#x1f52d; Hi,I’m Pleasure1234&#x1f331; I’m currently learning Vue.js,SpringBoot,Computer Security and so on.&#x1f46f; I’m studying in University of Nottingham Ningbo China&#x1f…

射线和平面求交

射线和平面求交 1、平面方程 如果已知平面的高度&#xff08;即沿法向量方向的距离&#xff09;为 height&#xff0c;平面方程可以表示为&#xff1a; n ^ ⋅ p h e i g h t \bold{\hat{n}} \cdot p height n^⋅pheight p p p 是平面上的任意一点 height 的正负取决于法向量…

W外链创建抖音私信卡片教程,私信卡片跳转微信工具

W外链地址wai.cn 在数字化时代的浪潮中&#xff0c;私域流量的价值愈发凸显&#xff0c;成为企业获取用户、建立品牌忠诚度、提升转化率的关键手段。抖音&#xff0c;作为当下最热门的短视频社交平台之一&#xff0c;其用户基数庞大、互动性强&#xff0c;为企业私域引流提供了…

一些颜色的RGB整理

(214,219,233) (215,220,230) (189,189,189) (193,210,240) (190,210,240) (0,60,119) (0,60,120) (230,230,250)

初识Docker及管理Docker

Docker部署 初识DockerDocker是什么Docker的核心概念镜像容器仓库 容器优点容器在内核中支持2种重要技术&#xff1a;Docker容器与虚拟机的区别 安装Docker源码安装yum安装检查Docker Docker 镜像操作配置镜像加速器&#xff08;阿里系&#xff09;搜索镜像获取镜像查看镜像信息…

计算机网络技术期末复习

一. 填空 在采用电信号表达数据的系统中&#xff0c;数据有 数字数据 和 模拟数据 两种。域名系统DNS是一个 分布式数据库 系统。TCP/IP的网络层最重要的协议是 IP互连网协议&#xff0c;它可将多个网络连成一个互连网。 4. 在TCP/IP层次模型的网络层中包括的协议主要有ARP 、…

科技出海|百分点科技智慧政务解决方案亮相非洲展会

近日&#xff0c;华为非洲全联接大会在南非约翰内斯堡举办&#xff0c;吸引政府官员行业专家、思想领袖、生态伙伴等2,000多人参会&#xff0c;百分点科技作为华为云生态合作伙伴&#xff0c;重点展示了智慧政务解决方案&#xff0c;发表《Enable a Smarter Government with Da…

Web开发:卡片翻转效果(HTML、CSS)

目录 一、实现效果 二、完整代码 三、实现过程 1、页面结构 2、初始样式 3、翻转效果 4、图片大小问题 一、实现效果 如下图所示&#xff0c;当鼠标移入某个盒子&#xff0c;就反转这个盒子&#xff0c;并显示其背面的内容——卡片翻转效果&#xff1b; 卡片翻转效果 二…