From d62eff9c96f223d87be114b85bdff28e9164855a Mon Sep 17 00:00:00 2001 From: unknown <2152890632@qq.com> Date: Thu, 26 Oct 2023 12:49:45 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BD=9C=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../20230923.md" | 93 ++ .../20231024.md" | 57 ++ .../20231025.md" | 850 ++++++++++++++++++ 3 files changed, 1000 insertions(+) create mode 100644 "06 \351\231\210\345\277\227\344\274\237/20230923.md" create mode 100644 "06 \351\231\210\345\277\227\344\274\237/20231024.md" create mode 100644 "06 \351\231\210\345\277\227\344\274\237/20231025.md" diff --git "a/06 \351\231\210\345\277\227\344\274\237/20230923.md" "b/06 \351\231\210\345\277\227\344\274\237/20230923.md" new file mode 100644 index 0000000..b3088e0 --- /dev/null +++ "b/06 \351\231\210\345\277\227\344\274\237/20230923.md" @@ -0,0 +1,93 @@ +#### E-R图查数据逻辑 + +**课程信息表(course_info):** + +字段:id(主键)、teacher_id(教师id 主键)、course_name(课程名称)、course_code(课程号)、course_type(课程类别)、course_score(学分) 、create_id(创建人)、create_time(创建时间) 、update_id (修改人) 、update_time(修改时间) + +**教师表(teacher_info):** + +字段:id(主键)、code(工号)、name(姓名)、sex(性别)、professional(职称)、create_id(创建人)、create_time(创建时间) 、update_id (修改人) 、update_time(修改时间) + + +**学生表(student_info):** + +字段:id(主键)、code(学号)、name(姓名)、sex(性别)、age(年龄)、class_name(专业班级)、create_id(创建人)、create_time(创建时间) 、update_id (修改人) 、update_time(修改时间) + + + +**学生课程关联表(student_course_info):** + +字段:id(主键)、stu_id(学生id)、cou_id(课程id)、socre(成绩)、create_id(创建人)、create_time(创建时间) 、update_id (修改人) 、update_time(修改时间)** +** + +#### 内连接 + +```mysql + +select * from a [inner] join b on a.key = b.key +``` + +#### 左外连接 + +```mysql + +select * from a left join b on a.key = b.key +``` + +#### 右外连接 + +```mysql + +select * from a right join b on a.key = b.key +``` + +#### 全外连接 + +```mysql +elect * from a full outer join b on a.key = b.key; +``` + +##### 上面的全外连接sql只在Oracle中适用,MYSQL中不支持,因此在MYSQL中想要实现全外连接,得用联合查询(union)实现 + +```MYSQL + +select * from a left join b on a.key = b.key +union +select * from a right join b on a.key = b.key + +``` + +##### E-R图概述 + +概念模型中最常用的方法就是实体-联系方法(Entity-Relationship approach),该方法用E-R图来描述现实世界的概念模型,即E-R模型。 + +该模型中包含实体、属性以及实体之间的联系。在E-R图中,用矩形表示实体,椭圆形表示属性,菱形表示实体之间的联系(联系也是可以有属性的) +E-R图也称实体-联系图(Entity Relationship Diagram),提供了表示实体类型、属性和联系的方法,用来描述现实世界的概念模型。 + +##### 基本的概念 + +实体:客观存在并且可以相互区分的事物为实体。可以是具体的人,事,物或者抽象的概念 + +属性:实体所具有的某一个特性就称为属性,一个实体可以由若干个属性来刻画。 + +码:唯一标识实体的属性集 + +域:属性的取值范围称为该属性的域 + +实体型:用实体名及其属性名集合来抽象和刻画同类实体称为实体型 + +实体集:同一类型实体的集合称为实体集 +联系:现实世界中事物内部以及事物之间的联系在信息世界中反映为实体内部的联系和实体之间的联系。包括实体内部的联系及实体之间的联系 + +其中码分为超码,候选码,主码,外码 +超码:一个或多个属性的集合,这些属性的组合可以使我们在一个实体集中唯一的标识一个实体 + +候选码:任意超码的真子集不能包括超码,则称其为候选码;超码包括候选码 + +主码: 其实主码一般指的就是主关键字。主关键字是表中的一个或多个字段,它的值用于唯一地标识表中的某一条记录,主关键字又可以称为主键。 主键可以由一个字段,也可以由多个字段组成,分别称为单字段主键或多字段主键。又称主码。 + +外码: 外码别称外键,具体来说就是比如说这个外码是相对于关系R来说的,但是如果相对于关系S来说的话是关系R中的主码,外码就是这个意思。 + +#### 数据库设计分6个阶段: + +需求分析、概念结构设计、逻辑结构设计、物理结构设计、数据库实施、数据库运行和维护。 \ No newline at end of file diff --git "a/06 \351\231\210\345\277\227\344\274\237/20231024.md" "b/06 \351\231\210\345\277\227\344\274\237/20231024.md" new file mode 100644 index 0000000..c4e84ca --- /dev/null +++ "b/06 \351\231\210\345\277\227\344\274\237/20231024.md" @@ -0,0 +1,57 @@ +#### 子查询的三种方式: + +```mysql +1.放在select后面当列来用,要求子查询的结果是单行单列 +2.放在group后面当表来用,要求子查询的结果要取一个别名 +3.放在where后面当条件用,此时有两种情况,一种是单行单列,此时条件可以用=<>,另一种是单列多行 + +条件中用in关键字时,()里的值会自动查重 +count(*)查询所有列包括null,可以换成常量,count(列名时)只统计该列名非null值时的数量 +``` + +```mysql +-- 1. 查询" 1 "课程比" 2 "课程成绩高的学生的信息(学号、姓名、性别、出生日期)及课程分数 +select s.student_id,student_name,gender,birthday,sc1,sc2 from student s,( +SELECT + s1.student_id,s1.score sc1,s2.score sc2 +FROM + score s1, + score s2 +WHERE + s1.score > s2.score + AND s1.student_id = s2.student_id + AND s1.course_id = 1 + AND s2.course_id = 2) as b + where s.student_id=b.student_id; +``` + +```mysql +12.select * from student where student_id in ( +SELECT + student_id +FROM + score +WHERE + course_id IN (select course_id from score where student_id=1) + and student_id<>01 +GROUP BY + student_id +having + count(course_id)=(select COUNT(course_id) from score where student_id=1)); +``` + +```mysql +-- 49. 查询下周过生日的学生 +SELECT * FROM Student +WHERE WEEK(birthday) = WEEK(NOW())+1; + + +year,month(),day +-- 50. 查询本月过生日的学生 +SELECT * FROM Student +WHERE month(birthday) = month(NOW()); + +-- 51. 查询下月过生日的学生 +SELECT * FROM Student +WHERE month(birthday) = month(NOW())+1; +``` \ No newline at end of file diff --git "a/06 \351\231\210\345\277\227\344\274\237/20231025.md" "b/06 \351\231\210\345\277\227\344\274\237/20231025.md" new file mode 100644 index 0000000..21b8795 --- /dev/null +++ "b/06 \351\231\210\345\277\227\344\274\237/20231025.md" @@ -0,0 +1,850 @@ +# 一、数据库设计 : + +```mysql +两个实体之间的关系: +1.一对一 将其中任一表主键,放到另一表当外键 +2.一对多的关系(多对一的关系) 将一所在表的主键,放到多的表当外键 如 +3.多对多的关系 必须有第三张表,作中转表,将前面两个表主键放进来当外键 +``` + +# 二、powerdesigner: + +```mysql +第一步:创建概念模型图(CDM)以用户角度 +第二步:转换逻辑模型图(LDM)以计算机角度 +第三步:转换物理模型图(PDM)以数据角度 +第四步:生成DDL +``` + +```mysql +RABC是基于角色的访问权限控制模型,在用户和权限中间建立一个角色做中转 +sku由一个商品的不同属性组成的最小存储单位 +``` + +# 三、常用函数: + +```mysql +1.日期,字符串,数学 +select now(); +select time(now()); +2.datediff(日期1,日期2) +返回日期1-日期2的天数差 +3.timestampdiff(单位,日期1,日期2) +select datediff('2022-10-20','2022-10-01') +select datediff(hour,'2022-10-20','2022-10-01') 返回指定内容 +4.将字符串格式化成日期对象: +select date_format('2010-10-10',%y); ---2010 +5.数学函数 +select rand(); +select floor(rand()*5+1); +6.小数取整:四舍五入,向下取整,向上取整 +select round(1.6,0) ---向上取整结果为2 +7.直接截取小数点 +select truncate(1.6455,2); ---1.64 +8.向上取整,将小数直接变1加到整数部分 +select ceil(1.000005); ---2 +9.向下取整,直接将小数部分全部直接扔掉,只保留整数部分 +select floo(1.999995); ---1 +10.abs()取绝对值 +select abc(-1); +11.字符串去空格,替换,拼接,截取,大小写 +去空格: +set @a=' 我们 是 小毛孩'; +set @b=' 你说的对 ' +去除字符串两端的空格: +select trim(@a); +去除字符串左端的空格 +select ltrim(@a); +去除字符串右端的空格 +set rtrim(@a); +12.替换: +select replace (replace(@a,'小毛','大男孩')); +13.拼接: +select replace(concat(@a,@b),'',''); +14.截取: +select substring(@a,1,1); +select substr(@b,1,1); +select mid(@b,1,1); +15.根据字符串截取字符串: +select substring('136-119-120',1,3) +16.大小写: +select upper('hEllO WorLD'); +select lower('hEllO WorLD'); +``` + +# 四、存储过程 + +### 1.概念: + +用于完成一次完整的业务处理,没有返回值,可通过传出参数给多个值,将一系列sql语句的执行过程存储到数据库中,并取一个名称,下次直接调用这个名称,就可以执行这一系列的sql语句了。 + +### 2.基本语法: + +(1)创建 + +存储过程分为有参、无参存储过程 + +```sql +delimiter // -- 修改定界符为//(符号可以自定义,只要不是 \ ) +CREATE PROCEDURE 存储过程名称 ([ in/out/inout 参数名 参数数据类型 ]) +BEGIN +-- 真正要执行的sql语句集合(集合的意思是sql语句可以是N条,可以是查询、插入、修改、删除语句,基本DDL)每句sql语句都用 ; 结束 +END // +delimiter ; -- 将定界符还原为 ; +``` + +(2)调用 + +```sql +call 名称 ([ 参数 ]); -- 如果()里没有参数,可以把()省略 +``` + + + +(3)查看 + +```sql + SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA = 'xxx'; + -- 查询指定数据库的存储过程及状态信息 +SHOW CREATE PROCEDURE 存储过程名称 ; +-- 查询某个存储过程的定义 +``` + +-- 删除 + +```sql + DROP PROCEDURE [ IF EXISTS ] 存储过程名称; + -- 存储过程不支持直接修改过程的语法,需要先删除原有的过程,再重新建一个同名的,删除时不需要加() +``` + + 注意: +在命令行中,执行创建存储过程的SQL时,需要通过关键字 delimiter 指定SQL语句的结束符。 + +(4)定义一个参数的语法包括参数模式、参数名称、参数数据类型 + +- IN输入参数:表示调用者向过程传入值(传入值可以是字面量或变量) +- OUT输出参数:表示过程向调用者传出值(可以返回多个值)(传出值只能是变量) +- INOUT输入输出参数:既表示调用者向过程传入值,又表示过程向调用者传出值(值只能是变量) + +存储过程可以有0个或多个参数,用于存储过程的定义。 + +① in 入参 + +② out 出参 + +```sql +delimiter // +create procedure 存储过程名称(in myid int,out myname varchar(20)) -- 传入编号传出名称 +begin +select first_name into myname from employees where employee_id=myid; +end // +delimiter ; +call 存储过程名称 (100,@newname); +select @newname; +``` + +③ inout 入参出参 + +```sql +delimiter // +create procedure 存储过程名称(inout myname varchar(20)) -- 传入含有空格的名字传出去除空格的名字 +begin +set myname=trim(myname); +end // +delimiter ; +set @name1=' 李小龙 ' +call 存储过程名称 (@name1); +select @name1; +``` + +注:在参数模式中只要含有out的,调用传参时,一定要用会话变量 + +# 五、变量 + +1.mysql中的变量分为两大类,一是系统的变量,二是用户的变量(可自定义的) + +用户变量可分为会话变量(成员变量)和局部变量 + +局部变量的作用域为begin和end之间 + +(1)系统变量:用@@global.变量名,指系统已经定义好的变量 + +(2)用户变量:可自定义的变量 + +① 会话变量:用@ 变量名表示 + + 作用域:同一会话中可任意调用,不用定义直接使用 + +② 局部变量:直接用,不带@标识符表示 + + 作用域:begin和end之间 + +注:使用局部变量前一定先定义,定义变量之前不能有其他语句 + +declare 变量名 变量数据类型 [defult 默认值] + +2.赋值方式 + +(1)方式一:直接赋值 + + 定义一个局部变量 + +```sql +declare myname varchar(10); +``` + +给变量赋值(通用、会话、局部也都是一样的)有两种方式、 + +```sql +set myname='小明'; +``` + +(2)方式二:将查询结果赋值给变量 + +```sql +declare myfname varchar(10); +declare mylname varchar(10); +select first_name,last_name into myfname,mylanme from employees where employee_id=100; +select myfname,mylname; +``` + +总结: ① set 变量名=值 + + ②select 值 into 变量; + +# 六、分支结构 + +### 1.if + +存储过程中是支持 if 这种条件判断的分支结构,但是不能用在 select 查询字段中 + +if 可以判断某个值也可以判断区间 + +语法: + +```sql +if 条件 then sql语句 +[elseif 条件2 then 语句2;] -- 语句后面要加; +…… +[ELSE 操作N] +END IF; +-- 关键字then后只能加语句 +``` + +### 2.case + +(1) + +```sql +case 表达式 +when 值1 then 结果1或语句1(如果是语句,需要加分号) +when 值2 then 结果2或语句2 +... +ELSE 结果n或语句n +end [case]; +-- 如果是放在begin end中需要加上case,如果放在select后面不需要 +``` + +(2) + +```sql +case +where 条件1 then 结果1或语句1(如果是语句,需要加分号) +where 条件2 then 结果2或语句2 +... +ELSE 结果n或语句n +end [case]; +-- 如果是放在begin end中需要加上case,如果放在select后面不需要 +``` + +# 七、循环 + +存储过程中的循环结构,任何循环一定会有一个改变循环条件的语句 + +1.loop 死循环 + +不需要条件的死循环(里面要有终止循环的条件) + +```sql +[loop_label:] LOOP +循环执行的语句 +END LOOP [loop_label] +-- loop 循环中关键字leave即可退出循环,也可以退出begin,必须要跟上标识符 +``` + +2.while 有条件的循环 + +一开始就明确了开始条件和结束条件,满足条件才会进入循环 + +```sql +WHILE 条件 DO -- 条件是为了进入循环 +SQL语句 +END WHILE; +``` + +3.repeat + +先执行一次,再判断是否符合循环的条件(条件是为了退出循环) + +```sql +REPEAT +循环体的语句 +UNTIL 结束循环的条件表达式 +END REPEAT; +``` + +# 八、存储函数 + +存储函数是有返回值的存储过程,存储函数的参数只能是IN类型的。 + +### 1.创建语法 + +```sql +CREATE FUNCTION 存储函数名称 (参数名 参数类型) (函数没有模式直接写类型) +RETURNS 返回值类型 -- 存储函数只能返回一个值,有返回值就要声明他的数据类型 +[characteristic ...] -- deterministic contain sql 或 deterministic no sql +BEGIN +-- SQL语句 一定要有return语句,return语句写在最后 +RETURN ...; +END ; +``` + +### 2.查询创建语句 + +```sql +show create function 函数名; +``` + +### 3.修改 + +跟存储过程一样先删再建 + +```sql +drop function 函数名; +``` + +### 4.调用 + +```sql +select 函数名(); +``` + +# 九、游标 + +### 1.定义游标 + +定义变量要放在定义游标之前 + +```sql +DECLARE 游标名称 CURSOR FOR 查询语句 ; +``` + +### 2.打开游标 + +```sql +OPEN 游标名称 ; +``` + +### 3.获取游标记录 + +(游标每次只取一样) + +```sql +FETCH 游标名称 INTO 变量 [, 变量 ] ; +``` + +### 4.关闭游标 + +```sql +CLOSE 游标名称 ; +``` + +示例: + +```sql +delimiter // +create procedure 名称() +begin +-- 定义变量要放在定义游标之前 +declare uname varchar(20); +declare usex int; +declare i int defult 1; +declare countnum int; +--定义游标 +declare 游标名称 cursor for select name,sex from student; +select count(*) into countnum from student; + +create table boy( +id int pirmary key, +uname varchar(50), +usex char(1) +); +create table girl( +id int pirmary key, +uname varchar(50), +usex char(1) +); + +-- 打开游标 +open 游标名称; + +while i<=countnum do +-- 使用游标:每次只取一样 +-- 从游标里取值并赋值给变量,有几个值就要几个变量,数量、位置、类型都要对得上 +fetch 游标名称 into uname,usex; +if usex=1 then insert into boy values (null,uname,'男'); +elseif usex=0 then insert into gril values (null,uname,'女'); +end if; +set i=i+1; +end while; +-- 关闭游标 +close 游标名称; +end // +delimiter; +``` + +## 处理错误 + +```sql +declare continue/exit handle for 1329 set flag=0; +open 游标名称; +whil flag is null do +....... +``` + +# 十、触发器 + +### 1.语法 + +```sql +delimiter // +create trigger 触发器名称 +before/ after(触发时机) insert/ update/ delete(触发类型) +on 表名 for each row -- 行级触发器 +begin +触发的语句 +end // +delimiter; +``` + +### 2.查看 + +```sql +show triggers; +``` + +### 3.删除 + +```sql +drop trigger 触发器名称; +``` + +### 4.故意报错 + +```sql +signal sqlstate 'MD001(随便五个字符)'set message_text='错误'; +``` + +# 十一、公共表达式(CTE) + +```sql +with 表达式名称 as (子查询) + +select/delete/update 语句; +``` + +支持多个表达式 + +# 十二、窗口函数 + +### 1.语法 + +```sql +窗口函数名称(参数) OVER([PARTITION BY 字段名 ORDER BY 字段名 ASC|DESC]) +-- partition by 分组 等价于 group by +或者是: +函数 OVER 窗口名 … WINDOW 窗口名 AS ([PARTITION BY 字段名 ORDER BY 字段名 ASC|DESC]) +-- OVER 关键字指定函数窗口的范围。 +``` + +### 2.序号函数 + +row_number()、rank()、dense_rank() + +① row_number():不管排名是否有相同,都按照顺序1,2,3,4...n + +② rank():排名相同的名次一样,相同的有几个,后面就跳过几次 + +③ dense_rank():排名相同的名词一样,且后面名次不跳跃 + +### 3.开窗聚合函数 + +sum()|avg()|min()|max()|count()| over (partition by ... order by...) + +### 4.窗口大小 + +① 当前行:current row + +② 前一行:preceding + +③ 后一行:following + +④ 起始行:unbounded preceding + +⑤ 最终行: unbounded following + +-- rows 启用窗口大小 +-- between ... and ... 范围区间 + +### 5.日期函数 + +(1)获取当前日期 + +```sql +select curdate(); +``` + +(2)获取当前时间 + +```sql +select curtime(); +``` + +(3)获取当前日期时间 + +```sql +select now(); +``` + +(4)从日期字符串获取日期 + +```sql +select date('2000-02-02'); +select date('2000-02-02 12:12:12'); -- 只获取日期 +``` + +(5)天数差 + +```sql +select datediff('2001-02-02','2000-02-02'); -- 前减后 +``` + +(6)指定差 + +```sql +select timestampdiff(day,'2001-02-02','2000-02-02'); -- 后减前 +``` + +(7) 日期减法 + +```sql +select subdate('2001-02-02',interval 2 day); +``` + +(8)日期加法 + +```sql +select adddate('2001-02-02',interval 2 day); +``` + +(9)获取某日期中的值 + +```sql +select year('2001-02-02'); +select day('2001-02-02'); +select dayofyear('2001-02-02'); +select dayofweek('2001-02-02'); +``` + +(10)获取该月最后一天 + +```sql +select last_day('2001-02-02'); +``` + +(11)日期格式 + +```sql +select date_format('2001-02-02','%Y'); +``` + +### 6.前后函数 + +返回当前行的前某一行的值,或者后某一行的值 + +lag(列名,前第n行) + +lead(列名,后第n行) + +### 7.头尾函数 + +返回第一个或最后一个列的值 + +first_value(列名) + +last_value(列名) + +# 十三、索引 + +是帮助mysql高效获取数据的数据结构 + +### 1.创建索引 + +```sql +create index 索引名 on 表格(列名); +``` + +```sql +alter table 表名 add index 索引名(列名); +``` + +```sql +create table 表名( +..... +index 索引名(列名) +); +-- 以这种方式定义的索引,可以不指定索引名称 +``` + +### 2.删除索引 + +```sql +drop index 索引名 on 表名; +``` + +```sql +alter table 表名 drop index 索引名; +``` + + + +### 3.查看表的索引 + +```sql +show index from 表名; +``` + + + +### 4.唯一索引 + +索引烈儿的值必须唯一,但允许有空值,如果是组合索引则列值的组合必须唯一。 + +创建语法: + +```sql +create unique index 索引名 on 表名(列名); +``` + +```sql +alter table 表名 add unique 索引名(列名); +``` + +```sql +create table 表名( +....... + unique[index] 索引名(列名) +); +``` + +(1)唯一索引必须有索引名,有唯一约束就会自动有唯一索引 + +(2)约束是没有名称和index关键字的 + +(3)删除唯一索引与删除普通索引相同 + +### 5.主键索引 + +(1)有主键约束就会有主键索引 + +(2)create index不能用来创建主键索引 + +(3)创建语法: + +```sql +create table 表名( +列表名 数值类型 primary key, + ...... +); +``` + +```sql +create table 表名( +........ + primary key (列名) +); +``` + +```sql +alter table 表名 add primary key (列名); +``` + +(4)删除主键索引 + +删除主键不用drop index + +```sql +alter table 表名 drop primary key; +``` + + + +### 6.联合索引 (遵循最左前缀法则) + +(1)普通联合索引 + +```sql +create index 索引名 on 表名 (列名1,列名2,列名3....); +``` + +(2)联合唯一索引 + +```sql +create unique index 索引名 on 表名 (列名1,列名2,列名3....); +``` + + + +### 7.explain 联合计划 + +用来查看某个查询语句的执行详细情况 + +语法: + +```sql +explain select.......from......; +``` + +# 十四、事务 + +### 1.事务的几个特性 + +(1)原子性 + +一组sql语句要么全部成功,要么全部失败,不存在部分成功,部分失败的情况 + +事务是一个原子操作,是最小的执行单元,由一个或多个sql语句组成,不可分割 + +(2)隔离性 + +一个事务的执行不能被其他事务干扰,一个事务内部的操作及使用的数据对并发的其他事务是隔离的 + +(3)一致性 + +一个事务必须使数据库从一个一致性状态变换到另一个一致性状态 + +(4)持久性 + +一个事务一旦提交,他对数据库中的数据的改变是永久性的 + +### 2.事务的隔离级别 + +(1)读未提交:read uncommited + +(2)读已提交:read commited + +一个事务操作过程中可以读取到其他事务已经提交的数据。 + +事务中的每次读取操作,读取到的都是数据库中其他事务已提交的最新的数据(相当于当前读) + +(3)可重复读:repeatable read + +一个事务操作中对于一个读取操作不管多少次,读取到的结果都是一样的。 + +(ps:不可重复读 + +在同一事务中,多次读取同一数据返回的结果有所不同,换句话说,后续读取可以读到另一事务已提交的更新数据。相反,“可重复读” 在同一事务中多次读取数据时, 能够保证所读数据一样, 也就是后续读取不能读到另一事务已提交的更新数据) + +(4)串行化:serializable + +### 3.是否开启隐式事务是由便来你autocommit控制的 + +### 4.事务分为隐式事务和显式事务 + +(1)mysql中事务默认是隐式事务,执行insert,update,delete操作的时候,数据库自动开启事务提交,回滚。 + +(2)显示事务需要手动开启、提交或回滚 + +### 5.开启事务 + +```sql +set commit=0; +或 +start transaction; -- 不管是隐式还是显示状态,都可以临时手动开启一次事务 +``` + + + +### 6.查看自动提交的状态 + +```sql +show variables like 'autocommit'; +``` + +### 7.关闭自动提交 + +```sql +set autocommit=off; +或 +set autocommit=0; +``` + +### 8.打开自动提交 + +```sql +set autocommit=on; +或 +set autocommit=1; +``` + +### 9.回滚操作 + +会将数据还原回事务初始状态 + +```sql +rollback; +-- 回滚有附加确认的效果,一旦确认事务就结束了 +``` + +### 10.提交事务 + +将数据持久化,也就是确认数据最终状态 + +```sql +commit; +``` + +### 11.savepoint关键字 + +将大批操作分为几个部分,然后指定回滚某个部分 + +```sql +..... +savepoint part1; +..... +savepoint part2; +..... +rollback part1; +-- 有保存点的事务是分段执行的,所以回滚到某个保存点不会结束整个事务 +..... +``` + +### 12.只读事务 + +表示在事务中执行的是一些只读操作,如查询,但不会做insert、update、delete操作 + +```sql +start transaction read only; +``` + +### 13.更新丢失 + +丢失更新就是两个不同的事务(或者Java程序线程)在某一时刻对同一数据进行读取后,先后进行修改。导致第一次操作数据丢失。 + +(1)第一类丢失更新 :A,B 事务同时操作同一数据,A先对改数据进行了更改,B再次更改时失败然后回滚,把A更新的数据也回滚了。(事务撤销造成的撤销丢失) + +(2)第二类丢失更新:A,B 事务同时操作同一数据,A先对改数据进行了更改,B再次更改并且提交,把A提交的数据给覆盖了。(事务提交造成的覆盖丢失) + +### 14.脏读 + +一个事务在执行的过程中读取到了其他事务还没有提交的数据。 \ No newline at end of file -- Gitee