From e2a22f4e90bbc6882700686315bd731da6feca85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E8=89=AF=E7=A1=BC?= <2242707601@qq.com> Date: Wed, 25 Oct 2023 11:38:08 +0000 Subject: [PATCH] =?UTF-8?q?=E5=90=B4=E8=89=AF=E7=A1=BC=E4=BD=9C=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 吴良硼 <2242707601@qq.com> --- ...30\347\272\247\347\254\224\350\256\260.md" | 641 ++++++++++++++++++ 1 file changed, 641 insertions(+) create mode 100644 "04\345\220\264\350\211\257\347\241\274/20231024MySQL\351\253\230\347\272\247\347\254\224\350\256\260.md" diff --git "a/04\345\220\264\350\211\257\347\241\274/20231024MySQL\351\253\230\347\272\247\347\254\224\350\256\260.md" "b/04\345\220\264\350\211\257\347\241\274/20231024MySQL\351\253\230\347\272\247\347\254\224\350\256\260.md" new file mode 100644 index 0000000..61a62d3 --- /dev/null +++ "b/04\345\220\264\350\211\257\347\241\274/20231024MySQL\351\253\230\347\272\247\347\254\224\350\256\260.md" @@ -0,0 +1,641 @@ +表与表之间的关系 1.一对一的关系 将其中任一表中的主键,放到另一个表当主键 2.一对多的关系 将一所在的表的主键放到多的表当外键 3.多对多的关系 必须第三张表,将前面两个表的主键放进来当外键 + +数据库的三大范式: + +**第一范式(确保每列保持原子性)** 第一范式就是每个属性,也就是字段要求不可再分割,也就要求有原子性 + +**第二范式** 在满足第一范式的基础上,要求非组件字段要完全依赖组件字段,有联合组件时,非组件要同时完成依赖这两个组件,而不能部分依赖 唯一性。 **第三范式** 独立性 消除传递依赖非组件值不依赖于另一个非组件值。简单的说,就是确保每列都和主键列直接相关,而不是间接相关 + +概念模型cdm 人的角度 + +逻辑模型Ldm 计算机的角度 + +物理模型pdm 从具体的数据库角度 + +RBAC的概念 + +RBAC即基于角色的访问控制,是一种流行的访问控制模型,它通过将用户分配到不同的角色,从而赋予用户相应的权限,保证了系统的安全性和完整性。RBAC模型的核心是角色,而不是用户,角色扮演者可以是用户、组织机构、应用程序等,而权限则是分配给角色,而非用户。 + +s p u:标准化产品单元,是一组可重复用,易检索的标准化信息的集合; + +s k u:库存量最小单位(最小库存单位):即库存进出的计量单位,在服装,鞋类产品中使用最普遍 + +json是一种轻量级的数据交换格式。它基于 [ECMAScript]的一个子集,采用完全独立于[编程语言](https://gitee.com/link?target=https%3A%2F%2Fbaike.baidu.com%2Fitem%2F%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80%2F9845131%3FfromModule%3Dlemma_inlink)的文本格式来存储和表示数据。简洁和清晰的[层次结构](https://gitee.com/link?target=https%3A%2F%2Fbaike.baidu.com%2Fitem%2F%E5%B1%82%E6%AC%A1%E7%BB%93%E6%9E%84%2F7658029%3FfromModule%3Dlemma_inlink)使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络[传输效率](https://gitee.com/link?target=https%3A%2F%2Fbaike.baidu.com%2Fitem%2F%E4%BC%A0%E8%BE%93%E6%95%88%E7%8E%87%2F7856651%3FfromModule%3Dlemma_inlink)。 + +```mysql +视图 + 介绍 +视图(View)是一种虚拟存在的表。视图中的数据并不在数据库中实际存在,行和列数据来自定义视 +图的查询中使用的表,并且是在使用视图时动态生成的。 +通俗的讲,视图只保存了查询的SQL逻辑,不保存查询结果。所以我们在创建视图的时候,主要的工作 +就落在创建这条SQL查询语句上。 + +-- 创建视图 +create or replace view stu_v_1 as select id,name from student where id <= 10; +-- 查询视图 +show create view stu_v_1; +select * from stu_v_1; +select * from stu_v_1 where id < 3; +-- 修改视图 +create or replace view stu_v_1 as select id,name,no from student where id <= 10; +alter view stu_v_1 as select id,name from student where id <= 10; +-- 删除视图 +drop view if exists stu_v_1; +``` + +```mysql +字符串函数 +CONCAT(S1,S2,...Sn) 字符串拼接,将S1,S2,... Sn拼接成一个字符串 +LOWER(str) 将字符串str全部转为小写 +UPPER(str) 将字符串str全部转为大写 +LPAD(str,n,pad) +左填充,用字符串pad对str的左边进行填充,达到n个字符 +串长度 +RPAD(str,n,pad) +右填充,用字符串pad对str的右边进行填充,达到n个字符串长度 +TRIM(str) 去掉字符串头部和尾部的空格 +SUBSTRING(str,start,len) 返回从字符串str从start位置起的len个长度的字符串 + + +数值函数 +CEIL(x) 向上取整 +FLOOR(x) 向下取整 +MOD(x,y) 返回x/y的模 +RAND() 返回0~1内的随机数 +ROUND(x,y) 求参数x的四舍五入的值,保留y位小数 + +日期函数 +CURDATE() 返回当前日期 +CURTIME() 返回当前时间 +NOW() 返回当前日期和时间 +YEAR(date) 获取指定date的年份 +MONTH(date) 获取指定date的月份 +DAY(date) 获取指定date的日期 +DATE_ADD(date, INTERVAL expr +type) +返回一个日期/时间值加上一个时间间隔expr后的 +时间值 +DATEDIFF(date1,date2) +返回起始时间date1 和 结束时间date2之间的天 +数 + + + 流程函数 + + +IF(value , t , f) +如果value为true,则返回t,否则返回 +f +IFNULL(value1 , value2) +如果value1不为空,返回value1,否则 +返回value2 +CASE WHEN [ val1 ] THEN [res1] ... +ELSE [ default ] END +如果val1为true,返回res1,... 否 +则返回default默认值 + +CASE [ expr ] WHEN [ val1 ] THEN +[res1] ... ELSE [ default ] END + +如果expr的值等于val1,返回 +res1,... 否则返回default默认值 +``` + +```mysql +存储过程 +介绍 +存储过程是事先经过编译并存储在数据库中的一段 SQL 语句的集合,调用存储过程可以简化应用开发 +人员的很多工作,减少数据在数据库和应用服务器之间的传输,对于提高数据处理的效率是有好处的。 +存储过程思想上很简单,就是数据库 SQL 语言层面的代码封装与重用。 +特点: +封装,复用 -----------------------> 可以把某一业务SQL封装在存储过程中,需要用到 +的时候直接调用即可。 +可以接收参数,也可以返回数据 --------> 再存储过程中,可以传递参数,也可以接收返回 +值。 +减少网络交互,效率提升 -------------> 如果涉及到多条SQL,每执行一次都是一次网络传 +输。 而如果封装在存储过程中,我们只需要网络交互一次可能就可以了。 + +基本语法 + 创建 +CREATE PROCEDURE 存储过程名称 ([ 参数列表 ]) +BEGIN +-- SQL语句 +END ; +调用 +CALL 名称 ([ 参数 ]); + +查看 + SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA = 'xxx'; -- 查询指定数据库的存储过程及状态信息 +SHOW CREATE PROCEDURE 存储过程名称 ; -- 查询某个存储过程的定义 + +删除 + DROP PROCEDURE [ IF EXISTS ] 存储过程名称; + + + 注意: +在命令行中,执行创建存储过程的SQL时,需要通过关键字 delimiter 指定SQL语句的 +结束符。 + + -- 存储过程基本语法 +-- 创建 +create procedure p1() +begin +select count(*) from student; +end; +-- 调用 +call p1(); +-- 查看 +select * from information_schema.ROUTINES where ROUTINE_SCHEMA = 'it'; + +show create procedure p1; +-- 删除 +drop procedure if exists p1; + + +参数的类型,主要分为以下三种:IN、OUT、INOUT。 具体的含义如下: +类型 含义 备注 +IN 该类参数作为输入,也就是需要调用时传入值 默认 +OUT 该类参数作为输出,也就是该参数可以作为返回值 +INOUT 既可以作为输入参数,也可以作为输出参数 + +CREATE PROCEDURE 存储过程名称 ([ IN/OUT/INOUT 参数名 参数类型 ]) +BEGIN +-- SQL语句 +END ; +案例 +根据传入参数score,判定当前分数对应的分数等级,并返回。 +score >= 85分,等级为优秀。 +score >= 60分 且 score < 85分,等级为及格。 +score < 60分,等级为不及格。 +create procedure p4(in score int, out result varchar(10)) +begin + if score >= 85 then + set result := '优秀'; + elseif score >= 60 then + set result := '及格'; + else + set result := '不及格'; + end if; +end; +-- 定义用户变量 @result来接收返回的数据, 用户变量可以不用声明 +call p4(18, @result); +select @result; +``` + +```mysql +在MySQL中变量分为三种类型: 系统变量、用户定义变量、局部变量。 +查看系统变量 +SHOW [ SESSION | GLOBAL ] VARIABLES ; -- 查看所有系统变量 +SHOW [ SESSION | GLOBAL ] VARIABLES LIKE '......'; -- 可以通过LIKE模糊匹配方式查找变量 + +SELECT @@[SESSION | GLOBAL] 系统变量名; -- 查看指定变量的值 + + + + +参数的类型,主要分为以下三种:IN、OUT、INOUT。 具体的含义如下: +IN 该类参数作为输入,也就是需要调用时传入值 默认 +OUT 该类参数作为输出,也就是该参数可以作为返回值 +INOUT 既可以作为输入参数,也可以作为输出参数 + +CREATE PROCEDURE 存储过程名称 ([ IN/OUT/INOUT 参数名 参数类型 ]) +BEGIN +-- SQL语句 +END ; + +全局变量(GLOBAL): 全局变量针对于所有的会话。 +会话变量(SESSION): 会话变量针对于单个会话,在另外一个会话窗口就不生效了。 + +局部变量 +DECLARE 变量名 变量类型 [DEFAULT ... ] ; +赋值 +SET 变量名 = 值 ; +SET 变量名 := 值 ; +SELECT 字段名 INTO 变量名 FROM 表名 ... ; +``` + +```mysql +if +if: 用于做条件判断,具体的语法结构为: +IF 条件1 THEN +..... +ELSEIF 条件2 THEN -- 可选 +..... +ELSE -- 可选 +..... +END IF; +在if条件判断的结构中,ELSE IF 结构可以有多个,也可以没有。 ELSE结构可以有,也可以没有。 + +//CASE +case结构及作用,和我们在基础篇中所讲解的流程控制函数很类似。有两种语法格式: +语法1: +-- 含义: 当case_value的值为 when_value1时,执行statement_list1,当值为 when_value2时, +执行statement_list2, 否则就执行 statement_list +CASE case_value +WHEN when_value1 THEN statement_list1 +[ WHEN when_value2 THEN statement_list2] ... +[ ELSE statement_list ] +END CASE; + +语法2: +-- 含义: 当条件search_condition1成立时,执行statement_list1,当条件search_condition2成 +立时,执行statement_list2, 否则就执行 statement_list +CASE +WHEN search_condition1 THEN statement_list1 +[WHEN search_condition2 THEN statement_list2] ... +[ELSE statement_list] +END CASE; + +注意:case语句要注意在select查询字段的时候可以(必须)不加分号还有结束的case也可以不写 +``` + +```mysql +while +while 循环是有条件的循环控制语句。满足条件后,再执行循环体中的SQL语句。具体语法为: +-- 先判定条件,如果条件为true,则执行逻辑,否则,不执行逻辑 +WHILE 条件 DO +SQL逻辑... +END WHILE; + +repeat +repeat是有条件的循环控制语句, 当满足until声明的条件的时候,则退出循环 。具体语法为: + +-- 先执行一次逻辑,然后判定UNTIL条件是否满足,如果满足,则退出。如果不满足,则继续下一次循环 +REPEAT +SQL逻辑... +UNTIL 条件 +END REPEAT; + + +loop +LOOP 实现简单的循环,如果不在SQL逻辑中增加退出循环的条件,可以用其来实现简单的死循环。 +LOOP可以配合一下两个语句使用: + +LEAVE :配合循环使用,退出循环。 +ITERATE:必须用在循环中,作用是跳过当前循环剩下的语句,直接进入下一次循环。 + +[begin_label:] LOOP +SQL逻辑... +END LOOP [end_label]; + +LEAVE label; -- 退出指定标记的循环体 +ITERATE label; -- 直接进入下一次循环 +``` + +```mysql +游标(CURSOR)是用来存储查询结果集的数据类型 , 在存储过程和函数中可以使用游标对结果集进 +行循环的处理。游标的使用包括游标的声明、OPEN、FETCH 和 CLOSE,其语法分别如下。 +声明游标 +DECLARE 游标名称 CURSOR FOR 查询语句 ; +打开游标 +OPEN 游标名称 ; +获取游标记录 +FETCH 游标名称 INTO 变量 [, 变量 ] ; + +关闭游标 +CLOSE 游标名称 ; + +条件处理程序 +条件处理程序(Handler)可以用来定义在流程控制结构执行过程中遇到问题时相应的处理步骤。具体 +语法为 +DECLARE handler_action HANDLER FOR condition_value [, condition_value] +... statement ; +handler_action 的取值: +CONTINUE: 继续执行当前程序 +EXIT: 终止执行当前程序 +condition_value 的取值: +SQLSTATE sqlstate_value: 状态码,如 02000 +SQLWARNING: 所有以01开头的SQLSTATE代码的简写 +NOT FOUND: 所有以02开头的SQLSTATE代码的简写 +SQLEXCEPTION: 所有没有被SQLWARNING 或 NOT FOUND捕获的SQLSTATE代码的简写 + +存储函数 +存储函数是有返回值的存储过程,存储函数的参数只能是IN类型的。具体语法如下: +CREATE FUNCTION 存储函数名称 ([ 参数列表 ]) +RETURNS type [characteristic ...] +BEGIN +-- SQL语句 +RETURN ...; +END ; + +characteristic说明: +DETERMINISTIC:相同的输入参数总是产生相同的结果 +DETERMINISTIC:相同的输入参数总是产生相同的结果 +READS SQL DATA:包含读取数据的语句,但不包含写入数据的语句。 +``` + +~~~mysql +# 触发器 + +触发器(trigger)是与表有关的数据库对象,指在insert/update/delete之前(BEFORE)或之后(AFTER),触发并执行触发器中定义的SQL语句集合。 + +事件A 对user表新增一条数据 姓名name 年龄age 性别sex + +事件B 对userlogs记录一条user表的操作 new.name,new.age + + + +触发器的这种特性可以协助应用在数据库端确保数据的完整性 , 日志记录 , 数据校验等操作。 + +使用别名OLD和NEW来引用触发器中发生变化的记录内容,这与其他的数据库是相似的。**触发器只支持行级触发** + + + +### 触发器的类型 + +| 类型 | NEW和OLD | +| ------ | ---------------------------------------- | +| insert | new代表将要新增或已新增的数据 | +| update | old代表更新前的数据、new代表更新后的数据 | +| delete | old代表将要删除或已删除的数据 | + + + +### 语法 + +创建触发器 + +```sql +create trigger 触发器名称 +before/after(触发时机) insert/update/delete(触发类型) +on 表名 for each row -- 行级触发器 +begin + 触发的语句... +end; +``` + +查看 + +```sql +show triggers; +``` + +删除 + +```sql +drop trigger 触发器名称; +``` +窗口函数 + +窗口函数的语法结构是: + +```mysql +函数 OVER([PARTITION BY 字段名 ORDER BY 字段名 ASC|DESC]) +``` + +或者是: + +```mysql +函数 OVER 窗口名 … WINDOW 窗口名 AS ([PARTITION BY 字段名 ORDER BY 字段名 ASC|DESC]) +``` + +* OVER 关键字指定函数窗口的范围。 + * 如果省略后面括号中的内容,则窗口会包含满足WHERE条件的所有记录,窗口函数会基于所有满足WHERE条件的记录进行计算。 + * 如果OVER关键字后面的括号不为空,则可以使用如下语法设置窗口。 +* 窗口名:为窗口设置一个别名,用来标识窗口。 +* PARTITION BY子句:指定窗口函数按照哪些字段进行分组。分组后,窗口函数可以在每个分组中分别执行。 +* ORDER BY子句:指定窗口函数按照哪些字段进行排序。执行排序操作使窗口函数按照排序后的数据记录的顺序进行编号。 +* FRAME子句:为分区中的某个子集定义规则,可以用来作为滑动窗口使用。 + +### 序号函数 + +row_number()、rank()、dense_rank() + + + +### 开窗聚合函数 + +```sql +sum()|avg()|min()|max()|count()| over (partition by ... order by...) +``` + +案例: + +```sql +# 获取各部门薪金总和(合计) +select ename,hiredate,deptno,sal, +sum(sal) over(partition by deptno) 'sum' +from emp; + +# 获取各部门薪金总和(累加) +select ename,hiredate,deptno,sal, +sum(sal) over(partition by deptno order by sal) 'sum' +from emp; +``` + + + +#### 窗口大小 + +```sql +# 开窗范围 +# 获取各部门薪金总和(范围:初始行至当前行) +select ename,hiredate,deptno,sal, +sum(sal) over(partition by deptno rows between unbounded preceding and current row) 'sum' +from emp; + +-- rows 启用窗口大小 +-- between ... and ... 范围区间 +-- unbounded preceding 起始行 +-- current row 当前行 +``` +公用表表达式 +公用表表达式(或通用表表达式)简称为CTE(Common Table Expressions)。CTE是一个命名的临时结 果集,作用范围是当前语句。CTE可以理解成一个可以复用的子查询,当然跟子查询还是有点区别的, CTE可以引用其他CTE,但子查询不能引用其他子查询。所以,可以考虑代替子查询。 + +依据语法结构和执行方式的不同,公用表表达式分为 普通公用表表达式 和 递归公用表表达式 2 种。 +1.普通公用表表达式 +ITH CTE名称 +AS (子查询) +SELECT|DELETE|UPDATE 语句; + +with + a as ( select department_id, min(hire_date) a1 from employees GROUP BY department_id ), + b as ( select department_id, max(hire_date) b1 from employees GROUP BY department_id ) +select a.department_id,a1 最早入职,b1 最晚入职 from a,b where a.department_id = b.department_id; + +普通公用表表达式类似于子查询,不过,跟子查询不同的是,它可以被多次引用,而且可以被其他的普 通公用表表达式所引用。 + +2.递归公用表表达式 +递归公用表表达式也是一种公用表表达式,只不过,除了普通公用表表达式的特点以外,它还有自己的特点,就是可以调用自己。它的语法结构是: + +```mysql +WITH RECURSIVE +CTE名称 AS (子查询) +SELECT|DELETE|UPDATE 语句; +``` + +递归公用表表达式由 2 部分组成,分别是种子查询和递归查询,中间通过关键字 UNION [ALL]进行连接。 这里的种子查询,意思就是获得递归的初始值。这个查询只会运行一次,以创建初始数据集,之后递归 查询会一直执行,直到没有任何新的查询数据产生,递归返回。 +~~~ + +```mysql +-- 比例函数 返回<= 或 >= 当前行的所有数占总行数的比率 +cume_dist() over(order by 字段 desc) -- 大于 +-- 分组函数 +ntile(组的数量) over(partition by 分组字段 order by 分组依据) + +-- 前后函数 +lag(字段,n) over(partition by 分组字段 order by 排序字段) -- 前n行 +lead(字段,n) over(partition by 分组字段 order by 排序字段) -- 后n行 +-- 窗口大小 +函数() over(partition by 字段 rows between 起始行 and 结束行) + -- rows 启用窗口大小 + -- between ... and ... 范围区间 + -- unbounded preceding 起始行 + -- n preceding 前n行 + -- current row 当前行 + -- n following 后n行 + -- unbounded following 最终行 + +-- 指定差 +timestampdiff(返回日期类型,日期1,日期2); -- 后面的日期减前面的日期 + -- 返回日期类型:year:年,month:月,day:日 +``` + +~~~MySQL +索引 +索引(index)是帮助MySQL高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足 +特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据, 这样就可以在这些数据结构 +上实现高级查找算法,这种数据结构就是索引。 + + 二叉树 + +索引分类 +分类 含义 特点 关键字 +主键索引 针对于表中主键创建的索引默认自动创建, 只能有一 PRIMARY +唯一索引 +避免同一个表中某数据列中的值重复 可以有多个 UNIQUE +常规索引 +快速定位特定数据 可以有多个 +全文索引 +全文索引查找的是文本中的关键词,而不是比较索引中的值 +可以有多个 FULLTEXT + ## 单列索引 + +#### 创建索引(普通索引) + +这是最基本的索引,它没有任何限制。它有以下几种创建方式: + +-- 方式一和二是给现成表加索引 + +方式一:直接在已有表中创建索引 + +```sql +create index 索引名 on 表名(列名) -- 直接删除索引 drop index 索引名 on 表名; 这种不能用来创建主键索引 +``` + +方式二:修改表结构追加普通索引 + +```sql +alter table 表名 add index 索引名(列名); -- 修改表结构删除索引 alter table 表名 drop index 索引名; +``` + +方式三:创建表的时候直接指定 + +```sql +create table 表名( + aaa int primary key, + bbb varchar(20), + index 索引名 (列名) -- 以这种模式定义的索引,可以不指定索引名称。 + primary key(列名) +); +``` + +#### 查看表的索引 + +```sql +show index from 表名; +``` + +可以查看到创建在表上的所有索引名称。 + + + +#### 删除索引 + +```sql +drop index 索引名 on 表名; +``` + +并且删除表时,会一并删除表上的全部索引。 + +```sql +alter table 表名 drop index 索引名; +``` + + + +#### 唯一索引 + +它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。它有以下几种创建方式 + +```mysql +create unique index 索引名 on 表名(列名); -- 创建普通索引的基础上。多了unique关键字 +``` + + 在已存在的表上追加唯一索引 + +```mysql +alter table 表名 add unique 索引名 (列名) +``` + + 创建表的时候直接指定 +~~~ + +```mysql +1.什么是事务? +数据库中的事务是指对数据库执行一批操作,在同一个事务当中,这些操作最终要么全部执行成功,要么全部失败,不会存在部分成功的情况。 + +2.事务的几个特性(ACID) -重点 +一个事务一旦提交,他对数据库中数据的改变就应该是永久性的。当事务提交之后,数据会持久化到硬盘,修改是永久性的。 +3、Mysql中事务操作 +mysql中事务默认是隐式事务,执行insert、update、delete操作的时候,数据库自动开启事务、提交或回滚事务。 + +是否开启隐式事务是由变量autocommit控制的。 + + +//设置不自动提交事务 +set autocommit=0; +//执行事务操作 +commit|rollback; +5、savepoint关键字 +savepoint part1;//设置一个保存点 +rollback to part1;//将savepint = part1的语句到当前语句之间所有的操作回滚 + +只读事务 +表示在事务中执行的是一些只读操作,如查询,但是不会做insert、update、delete操作,数据库内部对只读事务可能会有一些性能上的优化。 +start transaction read only; +6、事务中的一些问题(重点) +这些问题主要是基于数据在多个事务中的可见性来说的。也是并发事务产生的问题。 + +更新丢失 +丢失更新就是两个不同的事务(或者Java程序线程)在某一时刻对同一数据进行读取后,先后进行修改。导致第一次操作数据丢失。 + +第一类丢失更新 :A,B 事务同时操作同一数据,A先对改数据进行了更改,B再次更改时失败然后回滚,把A更新的数据也回滚了。(事务撤销造成的撤销丢失) + +第二类丢失更新:A,B 事务同时操作同一数据,A先对改数据进行了更改,B再次更改并且提交,把A提交的数据给覆盖了。(事务提交造成的覆盖丢失) + +脏读 +一个事务在执行的过程中读取到了其他事务还没有提交的数据。 这个还是比较好理解的。 + +读已提交 +从字面上我们就可以理解,即一个事务操作过程中可以读取到其他事务已经提交的数据。 + +事务中的每次读取操作,读取到的都是数据库中其他事务已提交的最新的数据(相当于当前读) + +不可重复读 +在同一事务中,多次读取同一数据返回的结果有所不同,换句话说,后续读取可以读到另一事务已提交的更新数据。相反,“可重复读” 在同一事务中多次读取数据时, 能够保证所读数据一样, 也就是后续读取不能读到另一事务已提交的更新数据。 +可重复读 +一个事务操作中对于一个读取操作不管多少次,读取到的结果都是一样的。 + +幻读 +脏读、不可重复读、可重复读、幻读,其中最难理解的是幻读 +7、事务的隔离级别 +隔离级别分为4种: +读未提交:READ-UNCOMMITTED +读已提交:READ-COMMITTED +可重复读:REPEATABLE-READ +串行:SERIALIZABLE +查看隔离级别 +show variables like 'transaction_isolation'; + +``` \ No newline at end of file -- Gitee