【MySQL】索引 事务

目录
一、索引
概念
作用
使用场景
使用
查看索引
创建索引
删除索引
背后的数据结构
二、事务
为什么使用事务
事务的概念
使用
开启事务
执行多条 SQL 语句
回滚或提交:rollback/commit;
事务的基本特性
原子性
一致性
持久性
隔离性
脏读
不可重复读
幻读
隔离级别
read uncommitted 读未提交
read committed 读已提交
repeatable read 可重复读
serializable 串行化
一、索引
概念
索引是一种特殊的文件,包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引,并指定索引的类型,各类索引有各自的数据结构实现。
📕类似于书的目录
作用
所谓的 "索引" 就相当于是在数据库中,构建一个特殊的 "目录"(在硬盘上的一系列特定的数据结构),通过这样的数据结构,加快查询的速度,尽可能避免针对表数据的遍历操作。
🔅数据库中的表、数据、索引之间的关系,类似于书架上的图书、书籍内容和书籍目录的关系。
🔅索引所起的作用类似书籍目录,可用于快速定位、检索数据。
🔅索引对于提高数据库的性能有很大的帮助。

⏩加快查询速度
使用场景
引入索引,是能够提高查询的速度,也会付出一些代价
1️⃣引入索引,需要消耗额外的存储空间。
2️⃣引入索引之后,确实能提高查询的效率,但是可能会影响到增删改的效率。
(有的时候增删改会更慢-增删改的时候需要同步的更新维护索引,有的时候会更快,有的时候,没啥变化)
要考虑对数据库表的某列或某几列创建索引,需要考虑以下几点:
⚫️数据量较大,且经常对这些列进行条件查询。
⚫️该数据库表的插入操作,及对这些列的修改操作频率较低。
⚫️索引会占用额外的磁盘空间。
满足以上条件时,考虑对表中的这些字段创建索引,以提高查询效率。
反之,如果非条件查询列,或经常做插入、修改操作,或磁盘空间不足时,不考虑创建索引。
索引,有利有弊,但是即使如此,实际开发中,还是比较鼓励使用索引的
1️⃣硬盘往往不是主要矛盾。
2️⃣对于增删改也不一定都是负面影响,也可能会触发一些正面效果。另一方面,很多业务场景,查询的频率比增删改要高很多。
使用
创建主键约束(PRIMARY KEY)、唯一约束(UNIQUE)、外键约束(FOREIGN KEY)时,会自动创建对应 列 的索引。
查看索引
show index from 表名;
👁🗨案例:查看学生表已有的索引
show index from student;

上述是针对 id 列创建索引,接下来查询的时候以 id 为条件的时候,才能够使索引生效,才能够提升查询速度。同样的,如果是针对 name 列创建索引,接下来查询应以 name 为条件,才能使索引生效。
一个表也可以允许有多个索引,就像词典有
拼音目录

部首目录

笔画目录


drop table student;
create table class(classId int primary key,className varchar(20));
show index from student;

创建索引
对于非主键、非唯一约束、非外键的字段,可以创建普通索引
create index 索引名 on 表名(列名);
👁🗨案例:创建班级表中,name 字段的索引
create index name_index on student(name);
show index from student;

🛑创建索引,也是一个 "危险操作",如果是针对空表,或者表中的数据比较少(几干,几万…)创建索引,就谈不上危险不危险,一旦表的数据量比较大,干万级别,此时创建索引操作,就可能会触发大量的硬盘 IO,直接把机器就搞的卡死住了。所以在最初建表的时候都要有哪些索引,提前规划好,创建好。
删除索引
drop index 索引名 on 表名;
☄️只能删除自己创建的索引,不能删除自动生成的
👁🗨案例:删除班级表中 name 字段的索引
drop index name_index on student;

背后的数据结构
所谓的 "构建索引" 其实就是引入一些数据结构,对数据进行存储,从而提高查找的速度
B + 树 是专门为数据库索引量身定做的一种特殊的数据结构
二、事务
为什么使用事务
事务是用来解决一类特定场景的问题的,有些场景中,完成某个操作,需要多个 SQL 配合完成的
例如下面的转账过程
drop table if exists accout;
create table accout(
id int primary key auto_increment,
name varchar(20) comment '账户名称',
money decimal(11,2) comment '金额'
);
insert into accout(name, money) values
('阿里巴巴', 5000),
('四十大盗', 1000);
比如说,四十大盗把从阿里巴巴的账户上偷盗了2000元
--阿里巴巴账户减少2000
update accout set money=money-2000 where name = '阿里巴巴';
-- 四十大盗账户增加2000
update accout set money=money+2000 where name = '四十大盗'
假如在执行以上第一句 SQL 时,出现网络错误,或是数据库挂掉了,阿里巴巴的账户会减少2000,但是四十大盗的账户上就没有了增加的金额。
解决方案:使用事务来控制,保证以上两句 SQL 要么全部执行成功,要么全部执行失败。
事务的概念
事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部失败。
在不同的环境中,都可以有事务。对应在数据库中,就是数据库事务。
即把多个要执行的 SQL,打包成一个 "整体",这个 "整体" 在执行过程中就能够做到要么整个都执行完,要么就一个都不执行。就可以避免出现上述转账一半的中间状态。
此处的 "一个都不执行" 不是这些 SQL 真的没执行,而是执行一半,发现出错的时候数据库会自动进行 "还原操作",相当于把前面执行过的 SQL 给进行 "撤销",最终的效果就看起来好像是一个都没执行这样的效果。这样的机制,称为 "回滚"(rollback)。同时,也把事务支持的上述的 "特性" 称为 "原子性"(过去人们以为 "原子" 就是不可拆分的最小单位了)。类似于商家把顾客退回的货重新卖出去。
数据库如何知道,具体是怎样回滚的?如何知道,前面的SQL做出了啥样的修改呢?数据库内部存在一系列的 "日志体系",记录到 "文件" 中,当开启事务的时候,此时每一步执行的SQL,都对数据进行了哪些修改,这些信息就会记录在案,后续如果需要回滚,就可以参考之前记录的内容,进行还原了。由于是记录在 "文件" 中,所以既可以应对 "程序崩溃",也能应对 "主机掉电"(虽然掉电,但是回滚的日志还是存在的,此时下次主机上电,下次数据库启动的时候就可以根据回滚日志的内容,就进行回滚操作了)。
问题来了,drop database这样的操作能回滚回来吗?不能的。回滚操作,只是针对 "事务" 来说的,开启事务之后,就会记录回滚日志,事务执行过程中,出现问题,自动触发回滚。一方面,drop database这样的操作不能放到事务中去执行,另一方面,这个操作,也不算执行出错,算是 "正确执行了SQL",开启事务之后,一个事务内,虽然是执行多个 SQL,执行的内容也不能太多。
🍀事务最核心的特性,就是原子性,能够解决的问题,就是批量执行 SQL 的问题
🍀除了转账之外,还有新生登记(可能需要往学生表/班级表同时插入数据)
🍀电商网站上下单(可能需要改商品表的库存数据/新增订单数据)
使用
开启事务
start transaction;
执行多条 SQL 语句
-- 阿里巴巴账户减少2000
update accout set money=money-2000 where name = '阿里巴巴';
-- 四十大盗账户增加2000
update accout set money=money+2000 where name = '四十大盗';
回滚或提交:rollback/commit;
commit;
说明:rollback 即是全部失败,commit 即是全部成功。
事务的基本特性
原子性
最重要的特性
一致性
描述的是事务执行前和执行后,数据库中的数据,都是 "合法状态",不会出现非法的临时结果的状态,类似于对账的过程
持久性
事务执行完毕之后,就会修改硬盘上的数据,事务都是会持久生效的
隔离性
描述了多个事务并发执行的时候,相互之间产生的影响是怎样的,MySQL 是一个 "客户端-服务器" 结构的程序,一个服务器,通常会给多个客户端同时提供服务因此,很可能,这多个客户端,就同时给这个服务器提交事务来执行,与之相对,服务器就需要同时执行这多个事务,此时就是 "并发" 执行,此时,如果这些同时执行的事务,恰好也是针对同一个表进行一些增删改查,此时就可能会在并发执行事务的过程中涉及三个问题。
脏读
有两个事务 A 和 B 并发执行,其中事务 A 在针对某个表的数据进行修改,A 执行过程中,B 也去读取这个表的数据,当 B 读完之后,A 把表里的数据又改成别的。这就导致,B 读到的数据,就不是最终的 "正确数据",而是读到了临时性的,"脏数据"(往往指的是 "数据过期,过时了",错误的数据)。
⚠️解决方案:在修改的时候给写操作 “加锁”,设置成不可读。
不可重复读
此时,有三个事务,A B C。首先,事务 A 执行一个修改操作,A 执行完毕的时候,提交数据。
接下来事务 B 执行,事务 B 读取刚才 A 提交的数据,在 B 读取的过程中,又来了一个事务 C,C又对刚才 A 修改的数据再次做出了修改,此时对于B来说,后续再读取这个数据,读到的结果就和第一次读到的结果是不一样的,这个过程就叫做 "不可重复读",体现的是事务 B,在一个事务里多次读取的结果不一样的。如果是有多个事务,每个事务读到的数据不一样,这种情况认为是正常的。
⚠️解决方案:给读操作 “加锁”,一个事务在读取数据的过程中,其他的事务不能修改它正在读的数据
幻读
不可重复的的特殊情况,有一个事务 A 在读取数据,读的过程中,另外一个事务 B,新增了/删除了一些其他的数据,此时站在 A 的视角,多次读取的数据内容虽然一样,但是 "结果集" 不同。
⚠️解决方案:“串行化”,比如多个客户端,同时提交了多个事务过来,但是服务器一个一个的执行事务(执行完第一个事务,再执行第二个,再执行第三个…)
隔离级别
在 MySQL 中提供了四个隔离级别,可以通过配置文件来设置当前服务器的隔离级别是哪个级别,设置不同的隔离级别,就会使事务之间的并发执行的影响产生不同的差别,从而会影响到上述的三个问题的情况。
read uncommitted 读未提交
这种情况下,一个事务可以读取另一个事务未提交的数据,此时,就可能会产生脏读,不可重复读,幻读三种问题,但是此时,多个事务并发执行程度是最高的,执行速度也是最快的
read committed 读已提交
这种情况下,一个事务只能读取另一个事务提交之后的数据(给写操作加锁了),此时,可能会产生不可重复读,幻读问题(脏读问题解决了),此时,并发程度会降低,执行速度会变慢,同时也称为事务之间的隔离性提高了,事务之间的相互影响变小了,得到的数据更准了
repeatable read 可重复读
这个情况下,相当于是给写操作和读操作都加锁了,此时,可能产生幻读问题,解决了脏读和不可重复读问题,并发程度进一步降低,执行速度进一步变慢,事务之间的隔离性,进一步提高了
serializable 串行化
MySQL默认的隔离级别,此时,所有的事务都是在服务器上一个接一个的执行的,此时,解决了脏读,不可重复读,幻读问题,但是并发程度最低,执行速度最慢,隔离性最高,数据最准确
根据需要,看需要执行速度快,还是数据比较准,来选择合适的隔离级别,准和快,无法兼得
相关文章:
【MySQL】索引 事务
目录 一、索引 概念 作用 使用场景 使用 查看索引 创建索引 删除索引 背后的数据结构 二、事务 为什么使用事务 事务的概念 使用 开启事务 执行多条 SQL 语句 回滚或提交:rollback/commit; 事务的基本特性 原子性 一致性 持久性 隔离性 脏读 …...
平台与架构:深度解析与开发实践
平台与架构:深度解析与开发实践 1. 什么是平台与架构? 平台(Platform):指操作系统或运行环境,例如 linux、windows、darwin(macOS)、android 等。架构(Architecture&…...
【Springboot+JPA】存储过程Procedure使用及踩坑记录
SpringbootJPA存储过程调用 存储过程实现1.表结构2.上报数据分页查询2.1先查出总条数2.1.1 创建存储过程2.1.2 实体类声明存储过程2.1.3 仓库方法绑定存储过程2.1.4 服务调用存储过程 2.2返回分页数据2.2.1 创建存储过程2.2.2 实体类声明存储过程2.2.3 仓库方法绑定存储过程2.2…...
<template>标签的作用,在构建可复用 UI 片段时如何应用?
大白话标签的作用,在构建可复用 UI 片段时如何应用 <template>标签的作用 在前端开发里,<template>标签可是个超棒的工具。它就像是一个“代码仓库”,可以把一些 HTML 代码片段存起来,而且这些代码片段在页面刚加载…...
Android Compose框架的值动画(animateTo、animateDpAsState)(二十二)
深入剖析 Android 框架的值动画(animateTo、animateDpAsState) 一、引言 在构建富有交互性和吸引力的 Android 应用界面时,动画起着至关重要的作用。值动画作为 Android 动画体系中的重要组成部分,能够为各种 UI 元素的属性变化…...
Gunicorn+Eventlet无法收到SocketIO发送的消息
GunicornEventlet无法收到Socketio发送的消息 介绍问题分析**1. 确保正确安装依赖库****2. 检查 Gunicorn 启动命令****3. 配置 Flask-SocketIO 的异步模式****4. 检查库版本兼容性****5. 确认 emit 的调用方式****6. 客户端连接检查** 如何使用多个workers?**1. 为什么不能直…...
【江协科技STM32】软件SPI读写W25Q64芯片(学习笔记)
SPI通信协议及S为5Q64简介:【STM32】SPI通信协议&W25Q64Flash存储器芯片(学习笔记)-CSDN博客 STM32与W25Q64模块接线: SPI初始化: 片选SS、始终SCK、MOSI都是主机输出引脚,输出引脚配置为推挽输出&…...
基于 Vue 3 的PDF和Excel导出
以下是基于 Vue 3 Composition API 的完整实现,包括 PDF 和 Excel 导出。 一、PDF 导出 (Vue 3) 安装依赖 在项目中安装相关库: npm install html2canvas jspdf Vue 3 代码实现 <template><div><div ref"pdfContent" cla…...
Git+Fork 入门介绍
git 分区理解 fork安装 从路径下去拿软件时,注意先拉到本地。经验来看,fork直接安装会出不可思议的问题。 fork操作 安装,注意设置好名字,如果之前安装的同学,名字没有写好,重新安装设置好名字。 clone操…...
Windows系统安装Node.js和npm教程【成功】
0.引言——Node.js和npm介绍 项目描述Node.js基于Chrome V8引擎的JavaScript运行环境,使JavaScript可用于服务器端开发。采用单线程、非阻塞I/O及事件驱动架构,适用于构建Web服务器、实时应用和命令行工具等npmNode.js的包管理器与大型软件注册表。拥有…...
Axure RP9.0 教程:左侧菜单列表导航 ( 点击父级菜单,子菜单自动收缩或展开)【响应式的菜单导航】
文章目录 引言I 实现步骤添加商品管理菜单组推拉效果引言 应用场景:PC端管理后台页面,左侧菜单列表导航。 思路: 用到了动态面板的两个交互效果来实现:隐藏/显示切换、展开/收起元件向下I 实现步骤 添加商品管理菜单组 在左侧画布区域添加一个菜单栏矩形框;再添加一个商…...
科技赋能|ZGIS综合管网智能管理平台守护地下城市生命线
地下管网作为城市公共安全的重要组成部分,担负着城市的信息传递、能源输送、排涝减灾等重要任务,是维系城市正常运行、满足群众生产生活需要的重要基础设施,是城市各功能区有机连接和运转的维系,因此,也被称为城市“生…...
react中useRef和useMemo和useCallback
memo : 被memo包裹的组件,会浅层比较 props,不会深度比较,如果浅层比较相同,就不会重新渲染组件 默认是,无论怎么,都会重新渲染一遍子组件,, useMemo: 包裹一个函数&am…...
如何保证LabVIEW软件开发的质量?
LabVIEW作为图形化编程工具,广泛应用于工业测控、自动化测试等领域。其开发模式灵活,但若缺乏规范,易导致代码可读性差、维护困难、性能低下等问题。保证LabVIEW开发质量需从代码规范、模块化设计、测试验证、版本管理、文档完善等多维度入手…...
如何快速解决 Postman 报错?
介绍一些 Postman 常见的报错与处理方法,希望能够对大家有所帮助。 Postman 一直转圈打不开的问题 Postman 报错处理指南:常见报错与解决方法...
基于数据挖掘从经验方和医案探析岭南名医治疗妇科疾病的诊疗和用药规律
标题:基于数据挖掘从经验方和医案探析岭南名医治疗妇科疾病的诊疗和用药规律 内容:1.摘要 背景:岭南地区独特的地理环境、气候条件及人文风俗使该地区妇科疾病具有一定特点,岭南名医在长期临床实践中积累了丰富的治疗经验。目的:基于数据挖掘…...
Android Launcher3 HotSeat文件夹创建禁止方案全解析
一、技术背景与实现原理 在Android 13 Launcher3定制开发中,需屏蔽HotSeat区域的文件夹创建功能。该功能涉及的核心事件处理流程如下: 复制 [拖拽事件] -> [Workspace.onDrop()] -> [CellLayout.performReorder()]└─> [createUserFolderIf…...
springboot body 转对象强验证属性多余属性抛错误
在Spring Boot中,当使用RequestBody注解来接收HTTP请求中的JSON数据并将其转换为Java对象时,Spring默认会忽略额外的属性。这意味着如果发送的JSON包含一些目标对象中没有定义的属性,Spring不会报错,这些额外的属性会被简单地忽略…...
C++手撕共享指针、多线程交替、LRU缓存
1. 共享指针 #include <atomic> #include <iostream>template <typename T> class sharedptr { private:T *ptr;std::atomic<size_t> *count;public:sharedptr(T *p) : ptr(p), count(new std::atomic<size_t>(1)) {}sharedptr(const sharedptr…...
Flask(三)路由与视图函数
在 Flask 中,路由 (Route) 是将 URL 地址映射到特定的视图函数 (View Function) 的机制。视图函数处理用户请求,并返回 HTTP 响应。理解路由和视图函数是构建 Flask 应用的基础。 3.1 路由的基本概念 Flask 使用 app.route() 装饰器来定义路由。以下是…...
c++中cpp文件从编译到执行的过程
C 文件从编写到执行的过程可以分为几个主要阶段:编写代码、预处理、编译、汇编、链接和运行。以下是每个阶段的详细说明: 1. 编写代码 这是整个过程的起点。程序员使用文本编辑器(如 VSCode、Sublime Text 或其他 IDE)编写 C 源…...
蓝桥杯1463:货物摆放问题详解——数学思维与代码优化
目录 一、题目分析与数学建模 二、直接暴力法的局限性 三、优化策略:因数分解与三元组枚举 步骤 1:收集所有因数 步骤 2:三元组枚举优化 四、代码实现与优化技巧 五、复杂度分析与性能提升 六、总结与拓展思考 关键点总结 拓展思考…...
C++ 多线程简要讲解
std::thread是 C11 标准库中用于多线程编程的核心类,提供线程的创建、管理和同步功能。下面我们一一讲解。 一.构造函数 官网的构造函数如下: 1.默认构造函数和线程创建 thread() noexcept; 作用:创建一个 std::thread 对象,但…...
如何设计一个处理物联网设备数据流的后端系统。
一、系统架构设计 物联网设备数据流的后端系统通常包括以下几个主要组件: ①设备数据采集层:负责从物联网设备收集数据。 ②数据传输层:负责将设备数据传输到后端系统。 ③数据处理层:实时或批量处理传输到后的数据。 ④存储层:负责存储设备数据。 ⑤API层:提供外部…...
【QT5 多线程示例】信号量
信号量 【C并发编程】(八)信号量 QT中的信号量类是QSemaphore,用法与C标准中的std::counting_semaphore类似。不同的是, QSemaphore无法指定最大计数。为了限定最大计数,可以采用两个QSemaphore信号量。下面使用一个…...
深入理解 Spring Boot 应用的生命周期:从启动到关闭的全流程解析
引言 Spring Boot 是当今 Java 开发中最流行的框架之一,它以简化配置和快速开发著称。然而,要真正掌握 Spring Boot,理解其应用的生命周期是至关重要的。本文将深入探讨 Spring Boot 应用的生命周期,从启动到关闭的各个阶段&…...
【算法笔记】图论基础(一):建图、存图、树和图的遍历、拓扑排序、最小生成树
目录 何为图论图的概念 图的一些基本概念有向图和无向图带权图连通图和非连通图对于无向图对于有向图 度对于无向图对于有向图一些结论 环自环、重边、简单图、完全图自环重边简单图 稀疏图和稠密图子图、生成子图同构 图的存储直接存边邻接矩阵存边邻接表存边链式前向星存边 图…...
SpringMVC 请求与响应处理详解
引言 在 Java Web 开发中,SpringMVC 作为 Spring 框架的重要模块,提供了强大的请求和响应处理机制。本文将深入探讨 SpringMVC 中请求和响应的处理方式,结合实际案例,帮助开发者更好地理解和应用这些功能。 一、SpringMVC 请求处…...
【python】requests 爬虫高效获取游戏皮肤图
1. 引言 在当今的数字时代,游戏已经成为许多人生活中不可或缺的一部分。而游戏中的皮肤,作为玩家个性化表达的重要方式,更是受到了广泛的关注和喜爱。然而,对于许多玩家来说,获取游戏皮肤往往需要花费大量的时间和精力…...
(UI自动化测试web端)第二篇:元素定位的方法_css定位之ID选择器
看代码里的【find_element_by_css_selector( )】( )里的表达式怎么写? 文章介绍了第一种写法id选择器,其实XPath元素定位要比CSS好用,原因是CSS无法使用下标(工作当中也是常用的xpath),但CSS定位速度比XPat…...
