MySQL事务和SQL优化
目录
一、什么是事务
二、事务的特征
三、MySQL使用事务
3.1 实现流程:
实现截图:
3.2 实例演示:
四、事务的隔离级别
幻读:
如何解决:
脏读:
不可重复读:
幻读和不可重复读两者区别:
事务的隔离级别:
五、数据库优化
5.1 影响性能因素的优化
5.2 参与优化的对象
5.3 系统优化
5.4 服务优化
5.5 MyISAM配置项
5.6 INNODB配置项
5.7 应用优化
库表设计原则:
索引建立原则(一)
索引建立原则(二)
编写高效的 SQL (一)
编写高效的 SQL (二)
一、什么是事务
事务(Transaction),是我们数据库内最小且不可再分的单元。通常一个事务对应一个完整的业务(例如银行账户转账业务,该业务就是一个最小的工作单元)。一个完整的业务需要批量的DML(INSERT 、UPDATE、DELETE)语句共同联合完成。事务只和DML语句有关,或者说DML语句才有事务。这个和业务逻辑有关,业务逻辑不同,DML语句的个数不同。
操作序列范畴,这些序列共有的一个特征 要么全部执行,要么全都不执行。这是一个不可分割的工作单元。事务是由事务开始和事务结束之间所执行的数据库操作组成。
#例如以银行转账需求:
家长账户 扣款 -money
学生账户 收款 +money
必要要求:以上两台DML语句必须同时成功或者同时失败。
最小单元不可再分,当第一条DML语句执行成功后,并不能将底层数据库中的第一个账户的数据修改,只是将操作进行了记录。这个记录实在内存中完成的,当第二条DML语句执行成功后,和底层数据库文件中的数据再进行完全的同步。反之如果第二条DML语句执行失败,清空所有的历史操作记录,以保证数据的统一。
事务处理(事务操作):保证所有事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式。当在一个事务中执行多个操作时,只有事务完成了提交行为。才意味着数据被永久的保存,要么数据库管理系统将放弃所有的修改。使整个事务回滚到最初状态。
二、事务的特征
事务的本质是由一组SQL语句组成的逻辑处理单元。
A (原子性Atomicity):原子性是指事务是一个不可分割的最小单元,事务中的操作要么都发生,要么都不发生;
C (一致性Consistency):事务必须使数据库从一个一致性,转变到另一个一致性的状态;
I (隔离性Isolation):多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他的事务操作所干扰,要求多个并发事务之间 要相互隔离;
D(持久性Durability):持久性指一个事务被提交是,它对于数据库内数据的改变就是永久性的,接下来即便数据库发生故障,也不应该对其有任何影响。

三、MySQL使用事务
3.1 实现流程:
1、手动关闭掉一个操作:自动提交改变成手动提交
SET AUTOCOMMIT = 0;
2、标记事务的起点
START TRANSACTION;
3、编辑并执行 SQL语句 组
4、提交
COMMIT;
5 、回滚
ROLLBACK;
6、手动开启掉一个操作:手动提交改变成自动提交
SET AUTOCOMMIT = 0;
实现截图:

MySQL 开启事务,回滚,提交
begin
5.5 以上版本 不需要手动begin,只要你执行的是一个DML,那么它就会自动在前面加入begin命令COMMIT 提交事务
完成了一个事务,一旦事务提交成功,就说明具备了ACID原则ROLLBACK 回滚职务
完成了一个事务,将内存中已执行的操作撤销,并还原成最初状态
3.2 实例演示:
#需求 顾客A在线购买了一个商品 价格XXXX元 采用转账方式进行支付
#假设A 存款金额XXXX元,且向卖家B支付购买商品费用
#卖家B 当前账户余额XXXX元#步骤1:创建数据库 shop_db;
CREATE DATABASE shop_db;
#步骤2:创建账户表 账户编号(自增) 账户人 当前账户金额
CREATE TABLE IF NOT EXISTS `account` (`id` int(11) not null auto_increment,`name` varchar(32) not null,`cash` decimal(9,2) not null,PRIMARY KEY (`id`)
) ENGINE=InnoDB;
#步骤3:通过事务完成转账业务
SET AUTOCOMMIT = 0;START TRANSACTION;
UPDATE account set cash = cash - 1000 WHERE name = 'A';
UPDATE account set cash = cash + 1000 WHERE name = 'B';COMMIT; #ROLLBACKSET AUTOCOMMIT = 1;#那么当两个事务打开同一个数据库(用户???),数据库原始余额为100;第一个事务将余额改为0,结束了;
#当第二个事务又将余额-50,那么最后结果是多少? #死锁 必须等待1事务结束后 方可执行2事务内的操作
四、事务的隔离级别
多个线程开启各自事务操作数据库中数据时,数据库系统要负责隔离操作,以保证各个线程在获取数据时的准确性。
如果不考虑隔离性会导致:幻读、脏读以及不可重复读
幻读:
在一个事务内读取到了别的事务插入的数据,导致前后读取的信息不一致。
EG:事务A按照自身的约定在进行数据读取,期间事务B插入了相同的搜索条件的新数据,事务A再次按照原先约定条件进行读取时,发现了事务B插入的新数据。
会造成事务中先产生的锁,无法管理后加入满足条件的行。
如何解决:
1、bin_log :产生数据一致性问题,在一个事务中,先对符合条件的目标行做变更,而在事务提交前,有新符合目标条件的加入。通过bin_log 恢复数据会将所有符合条件的目标行进行变更。
2、间隙锁:在两行记录间的空隙加上锁,防止新纪录的插入。
脏读:
事务读取到另一个事务未提交的数据,解决方案加入乐观锁。
不可重复读:
不可重复读是指在数据库访问中,一个事务范围内两个相同的查询却返回了不同数据,这是由于查询时系统中其他事务修改的提交而引起的。比如事务T1读取某一数据,事务T2读取并修改了该数据,T1为了对读取值进行检验而再次读取该数据,便得到了不同的结果。
幻读和不可重复读两者区别:
不可重复读指同一条SQL查询到了不同的结果,幻读指查询的结果行数不同。
事务的隔离级别:
| 描述 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| Read uncommitted | 是 | 是 | 是 |
| Read committed | 否 | 是 | 是 |
| Repeatable read | 否 | 否 | 是 |
| Serializable | 否 | 否 | 否 |
五、数据库优化
5.1 影响性能因素的优化
服务优化硬件操作系统网络数据库设计
应用优化应用程序查询事务管理数据分布
5.2 参与优化的对象
数据库管理员>
业务部门代表>
架构师>
应用程序设计开发人员>
硬件及系统管理员>
存储管理员...
5.3 系统优化
软件优化开发系统(操作系统)MYSQL编译优化
硬件优化CPU 内存 硬盘 网卡
5.4 服务优化
Mysql配置配置合理的Mysql服务器,尽量在应用本身达到一个合理的使用针对于不同的搜索引擎,定制不同的配置针对于不同的情况和需求,进行合理的配置my.cnf进行配置。
5.5 MyISAM配置项
| 选项 | 缺省值 | 推荐值 | 说明 |
|---|---|---|---|
| key_buffer_size | 8M | 128M--256M | 用来存放索引区块的缓存值, 建议128M以上,不要大于内存的30% |
| read_buffer_size | 128k | 10-20M | 用来做MyISAM表全表扫描的缓冲大小. |
| myisam_sort_buffer_size | 16M | 128M | 设置,恢复,修改表的时候使用的缓冲大小 |
5.6 INNODB配置项
| 选项 | 缺省值 | 推荐值 | 说明 |
|---|---|---|---|
| innodb_buffer_pool_size | 32M | 1G | InnoDB使用一个缓冲池来保存索引和原始数据, 这里你设置越大,你在存取表里面数据时所需要的磁盘I/O越少,一般是内存的一半,不超过2G,否则系统会崩溃,这个参数非常重要 |
| innodb_additional_mem_pool_size | 2M | 128M | InnoDB用来保存 metadata 信息,如果内存是4G,最好本值超过200M |
| innodb_flush_log_at_trx_commit | 1 | 0 | 0 代表日志只大约每秒写入日志文件并且日志文件刷新到磁盘; 1 为执行完没执行一条SQL马上commit; 2代表日志写入日志文件在每次提交后,但是日志文件只有大约每秒才会刷新到磁盘上. 对速度影响比较大,同时也关系数据完整性 |
| innodb_log_file_size | 8M | 128M | 在日志组中每个日志文件的大小, 一般是innodb_buffer_pool_size的25%,官方推荐是innodb_buffer_pool_size 的 40-50%, 设置大一点来避免在日志文件覆写上不必要的缓冲池刷新行为 |
| innodb_log_buffer_size | 128K | 8M | 用来缓冲日志数据的缓冲区的大小.推荐是8M,官方推荐该值小于16M,最好是 1M-8M 之间 |
5.7 应用优化
库表设计原则:
1、选择合适的数据类型:如果能够定长尽量定长;
2、使用 ENUM 而不是 VARCHAR,ENUM类型是非常快和紧凑的,在实际上,其保存的是TINYINT类型,但其显示为字符串。这样用这个字段来做一些选项列表变得相当的完美 ;
3、不要使用无法加索引的类型作为关键字段,比如TEXT类型;
4、为了避免联表查询,有时候可以适当的数据冗余,比如邮箱、姓名这些不容易更改的数据;
5、选择合适的表引擎,有时候 MyISAM 适合,有时候InnoDB适合;
6、为保证查询性能,最好每个表都建立有 auto_increment 字段, 建立合适的数据库索引;
7、最好给每个字段都设定 default 值。
索引建立原则(一)
1、一般针对数据分散的关键字进行建立索引,比如ID、QQ,像性别、状态值等等建立索引没有意义字段唯一,最少,不可为null;
2、对大数据量表建立聚集索引,避免更新操作带来的碎片;
3、尽量使用短索引,一般对int、char/varchar、date/time 等类型的字段建立索引;
4、需要的时候建立联合索引,但是要注意查询SQL语句的编写;
5、谨慎建立 unique 类型的索引(唯一索引);
6、大文本字段不建立为索引,如果要对大文本字段进行检索,可以考虑全文索引(引擎问题);
7、频繁更新的列不适合建立索引。
索引建立原则(二)
1、order by 字句中的字段,where 子句中字段,最常用的sql语句中字段,应建立索引;
2、唯一性约束,系统将默认为改字段建立索引;
3、对于只是做查询用的数据库索引越多越好,但对于在线实时系统建议控制在5个以内;
4、索引不仅能提高查询SQL性能,同时也可以提高带where字句的update,Delete SQL性能;
5、Decimal 类型字段不要单独建立为索引,但覆盖索引可以包含这些字段;
6、只有建立索引以后,表内的行才按照特地的顺序存储,按照需要可以是asc或desc方式;
7、如果索引由多个字段组成将最用来查询过滤的字段放在前面可能会有更好的性能。
编写高效的 SQL (一)
1、能够快速缩小结果集的 WHERE 条件写在前面,如果有恒量条件,也尽量放在前面;
2、尽量避免使用 GROUP BY、DISTINCT 、OR、IN 等语句的使用,避免使用联表查询和子查询,因为将使执行效率大大下降;
3、能够使用索引的字段尽量进行有效的合理排列,如果使用了联合索引,请注意提取字段的前后顺序;
4、针对索引字段使用 >, >=, =, <, <=, IF NULL和BETWEEN 将会使用索引;
5、如果对某个索引字段进行 LIKE 查询,使用 LIKE ‘%abc%’不能使用索引,使用 LIKE ‘abc%’将能够使用索引;
6、如果在SQL里使用了MySQL部分自带函数,索引将失效,同时将无法使用 MySQL 的 Query Cache,比如 LEFT(), SUBSTR(), TO_DAYS(),DATE_FORMAT(), 等,如果使用了 OR 或 IN,索引也将失效;
7、使用 Explain 语句来帮助改进我们的SQL语句。
编写高效的 SQL (二)
1、不要在where 子句中的“=”左边进行算术或表达式运算,否则系统将可能无法正确使用索引;
2、尽量不要在where条件中使用函数,否则将不能使用索引;
3、避免使用 select *, 只取需要的字段;
4、对于大数据量的查询,尽量避免在SQL语句中使用order by 字句,避免额外的开销;
5、如果插入的数据量很大,用select into 替代 insert into 能带来更好的性能;
6、采用连接操作,避免过多的子查询,产生的CPU和IO开销;
7、只关心需要的表和满足条件的数据;
8、适当使用临时表或表变量;
9、对于连续的数值,使用between代替in;
10、where 字句中尽量不要使用CASE条件;
11、尽量不用触发器,特别是在大数据表上;
12、更新触发器如果不是所有情况下都需要触发,应根据业务需要加上必要判断条件;
13、使用union all 操作代替OR操作,注意此时需要注意一点查询条件可以使用聚集索引,如果是非聚集索引将起到相反的结果;
14、当只要一行数据时使用 LIMIT 1,尽可能的使用 NOT NULL填充数据库;
15、拆分大的 DELETE 或 INSERT 语句批量提交SQL语句。
相关文章:
MySQL事务和SQL优化
目录 一、什么是事务 二、事务的特征 三、MySQL使用事务 3.1 实现流程: 实现截图: 3.2 实例演示: 四、事务的隔离级别 幻读: 如何解决: 脏读: 不可重复读: 幻读和不可重复读两者区别…...
[C语言]结构体初识
结构体定义 结构体是一些值的集合,被成为成员变量,结构的每个成员可以是不同类型的变量 声明: 定义了一个结构体比如以张蓝图,不占据内存,当你创建了一个结构体变量时,才占空间. #include<stdio.h>//struct 为结构体关键字, student 自定义结构体名称 struct student …...
跨平台开发:浅析uni-app及其他主流APP开发方式
随着智能手机的普及,移动应用程序(APP)的需求不断增长。开发一款优秀的APP,不仅需要考虑功能和用户体验,还需要选择一种适合的开发方式。随着技术的发展,目前有多种主流的APP开发方式可供选择,其…...
MyBatis常见面试题汇总
说一下MyBatis执行流程? MyBatis是一款优秀的基于Java的持久层框架,它内部封装了JDBC,使开发者只需要关注SQL语句本身,而不需要花费精力去处理加载驱动、创建连接等的过程,MyBatis的执行流程如下: 加载配…...
juc并发线程学习笔记(一)
本系列会更新我在学习juc时的笔记和自己的一些思想记录。如有问题欢迎联系。 并发编程 进程与线程 1.进程和线程的概念 程序是静态的,进程是动态的 进程 程序由指令和数据组成,但这些指令要运行,数据要读写,就必须将指令加载…...
力扣热门100题刷题笔记 - 3.无重复字符的最长子串
力扣热门100题 - 3.无重复字符的最长子串 题目链接:3. 无重复字符的最长子串 题目描述: 给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。示例: 输入: s "abcabcbb" 输出: 3 解释: 因为无重复字…...
达梦数据库死锁排查与解决
在达梦数据库系统中,死锁是指两个或多个事务相互等待对方释放资源,从而造成循环等待的现象,严重影响数据库的正常运行。以下是使用达梦数据库进行死锁排查和解决的具体步骤: 死锁查看 查询当前死锁信息 SELECT lc.lmode, lc.ta…...
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之TextClock组件
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之TextClock组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、TextClock组件 TextClock组件通过文本将当前系统时间显示在设备上。支持不同…...
CICD注册和使用gitlab-runner常见问题
1、现象 fatal: unable to access https://github.com/homebrew/brew/: 2、解决 git config --global --unset http.proxy git config --global --unset https.proxy 查看gitlab-runner是否成功: userusers-MacBook-Pro ~ % gitlab-runner -h 查看gitlab-run…...
关于Django部署
首先了解一下开发环境服务器跟生产环境服务器有何不同。 一、我们通过 python manage.py runserver 启动开发环境服务器,这条命令背后做了哪些事情? 1、首先加载Django项目的设置(settings) 2、检查数据库迁移,确保数…...
计算机网络——01什么是InterNet
什么是InterNet 1.1 什么是网络 由节点和边组成的与形状大小无关的拓扑 1.2 什么是Internet 从具体构成角度来说: 节点: 主机及其上运行的应用程序路由器、交换机等网络交换设备 边:通信链路 接入网链路:主机连接到互联网的链…...
刷存在感,Excel转Protobuf/Json通用配置文件
使用场景 最近工作流中有将Excel转Protobuf作为配置文件的技术方案。具体实现是先定一个proto文件,再在一个对应excel表中定义对应字段,由策划在excel进行更改。proto文件可以生成对应语言的脚本,然后将excel转成对应protobuf的binary。 我…...
docker 开放tcp连接供idea等其他外部工具开放使用
docker 开放tcp连接供idea等其他外部工具开放使用 方法一:通过systemd工具 sudo systemctl edit docker.service 修改文件内容如下 ExecStart/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375 重启 systemctl 配置 sudo systemctl daemon-reload 重启docker服务 s…...
虚拟机(VMware)ubuntu16.04 直接连接网口设备 USRP 吊舱
编辑虚拟网络编辑器 点击之后 选择网卡之后,点击确定。 电脑配置 使用了:192.168.2.56 虚拟机内部配置 和PC的配置一致...
告别繁杂的状态管理:Zustand 的简洁之道
1. Zustand Zustand 是一个轻量级的状态管理库,用于 JavaScript 应用程序,特别是在 React 生态系统中。它提供了一个简单、可扩展的解决方案来中心化和管理应用程序的状态。 与其他状态管理解决方案(如 Redux 或 MobX)相比&…...
CentOS磁盘扩容
参考操作 检查磁盘扩容情况 lsblk 使用fdisk命令进行开垦,有时需要重启之后才能进行下一步 fdisk /dev/新盘mkfs.ext4 /dev/新盘使用pvcreate直接创建虚拟卷 pvcreate /dev/新盘使用vgextend添加新创建的虚拟卷 vgextend 卷名称 /dev/新盘使用lvextend进行扩容…...
【数据分享】1929-2023年全球站点的逐日降雪深度数据(Shp\Excel\免费获取)
气象数据是在各项研究中都经常使用的数据,气象指标包括气温、风速、降水、能见度等指标,说到气象数据,最详细的气象数据是具体到气象监测站点的数据! 之前我们分享过1929-2023年全球气象站点的逐日平均气温数据、逐日最高气温数据…...
golang网络编程day4
golang网络编程day4 get和post的区别resful编程golang请求头golangheader内容类型和字符编码http请求头缓存和过期应用golang 请求头跨域请求应用http请求头用户代理应用golang响应头 get和post的区别 在前面的学习我只在应用场景上做了一个区别的举例,这里是进一步的学习有哪…...
为什么pgsql(内关联查询或者with字句时)会导致索引失效
1、在PostgreSQL中,内关联查询可能导致索引失效的原因通常与查询的过滤条件和数据分布有关。 以下是一些可能导致索引失效的情况: 1、使用了函数或类型转换:当查询条件中对索引字段使用了任何计算、函数或类型转换时,这可能会阻止…...
小程序 自定义组件和生命周期
文章目录 ⾃定义组件创建⾃定义组件声明组件编辑组件注册组件 声明引⼊⾃定义组件⻚⾯中使⽤⾃定义组件定义段与⽰例⽅法组件-⾃定义组件传参过程 小程序生命周期应用生命周期页面生命周期页面生命周期 ⾃定义组件 类似vue或者react中的自定义组件 ⼩程序允许我们使⽤⾃定义组件…...
springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 ,并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...
热门Chrome扩展程序存在明文传输风险,用户隐私安全受威胁
赛门铁克威胁猎手团队最新报告披露,数款拥有数百万活跃用户的Chrome扩展程序正在通过未加密的HTTP连接静默泄露用户敏感数据,严重威胁用户隐私安全。 知名扩展程序存在明文传输风险 尽管宣称提供安全浏览、数据分析或便捷界面等功能,但SEMR…...
yaml读取写入常见错误 (‘cannot represent an object‘, 117)
错误一:yaml.representer.RepresenterError: (‘cannot represent an object’, 117) 出现这个问题一直没找到原因,后面把yaml.safe_dump直接替换成yaml.dump,确实能保存,但出现乱码: 放弃yaml.dump,又切…...
