MySQL_2

目录

一、函数

1、字符串函数

2、数值函数

3、日期函数

4、流程控制函数

二、约束

1、概念:约束是作用于表中字段上的规则,用于限制存储在表中的数据。

2、目的:保证数据库中数据的正确、有效性和完整性。

3、分类 

4、外键约束

4.1添加外键的语法:

 此时我们已经无法删除dept表里的1

 4.2删除外键:

 4.3更新/删除行为:

 三、多表查询

1、多表关系

2、多表查询概述

3、内连接

4、外连接

5、自连接

6、联合查询    union / union all

        7、子查询

①标量 子查询

②列 子查询

③行 子查询

④表 子查询

8、多表查询案例

根据上面的学习与emp、dept和salgrade 3个表,实现11个案例:

最后再来3个表:student、student_course、course

四、事务

1、事务简介

2、事务操作

3、事务四大特性(ACID)

4、并发事务问题

5、事务隔离级别


一、函数

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从sta位置起的len个长度的字符串

使用:

select 函数/参数

测试:

-- concat

select concat('hello ','my ','world');


-- lower

select lower('hdADASDllo');


-- upper

select upper('hello');


-- lpad

select lpad('hello',8,'$');


-- rpad

select rpad('hello',8,'$');



-- trim 

select trim(' hel lo ');



-- substring

select substring('hello world',2,6);

 

 案例:

--1、由于业务需求变更,企业员工的工号,统一为5位数,目前不足5位数的全部在前面补0。比如: 1号员工的工号应该为00001

update emp set number =lpad(number,5,'0');


2、数值函数

常用的数值函数有:

CEIL(X)		向上取整
FLOOR(X)	向下取整
MOD(x;y)	返回x/y的模
RAND()		返回0~1内的随机数
ROUND(x;y)	求参数x的四舍五入的值,保留y位小数

测试:

-- ceil

select ceil(1.1);

 -- mod

select mod(7,4);

 -- rand

select rand();


-- round

select round(rand(),3);

 

 案例:

--2、通过数据库的函数,生成一个六位数的随机验证码

注意:如果直接这么写

select round(rand(),6)*1000000;
或
select round(rand()*1000000,0);

可能导致出现0.0xxxxx乘以100万,结果是xxxxx,只有5位数

 因此,我们可以使用字符串函数左右填充

这里我使用左填充,且填充的也是随机字符 

select lpad(round(rand(),6)*1000000,6,round(rand()*10,0));
或
select lpad(round(rand()*1000000,0),6,round(rand()*10,0));

 


3、日期函数

MySQL常见的日期函数:

CURDATE0)	返回当前日期
CURTIME()	返回当前时间
NOW()		返回当前日期和时间
YEAR(date)	获取指定date的年份
MONTH(date)	获取指定date的月份
DAY(date)	获取指定date的日期
DATE ADD(date,INTERVAL expr type)	返回一个日期/时间值加上一个时间间隔expr后的时间值
DATEDIFF(date1,date2)	返回起始时间date1 和结束时间date2之间的天数

测试:

-- curdate()

select curdate();



-- curtime()

select curtime();



-- now()

select now();

 -- year/month/day

select year(now());
select month(now());
select day(now());


-- date_add

select date_add(now(),interval 60 month); 60个月后的今天



-- datediff(前-后)

select datediff(now(),date_add(now(),interval 60 day));select datediff('2023-7-8','2020-6-8');

 

案例:

--3、查询所有员工的入职天数,并根据入职天数倒序排序

select name,datediff(curdate(),entryDate) as 'entryDays' from emp order by entryDays desc;


4、流程控制函数

流程函数也是很常用的一类函数,可以在SOL语句中实现条件筛选,从而提高语句的效率

IF(value, t, f)			如果value为true,则返回t,否则返回f
IFNULL(value1,value2)	如果value1不为空,返回value1,否则返回value2CASE WHEN [val1] THEN [res11 ... ELSE[ default] END	
如果val1为true,返回res1,... 否则返回default默认值CASE[expr] WHEN[val1] THEN[res1] ... ELSE[default] END	
如果expr的值等于val1,返回res1,...否则返回default默认值

测试:-- 查询emp表的员工姓名和工作地址,若工作地址为北京上海输出一线城市,其他输出二线

select name,workaddress,(case workaddress when '北京'  then '一线城市'when '上海'  then '一线城市'else '二线城市' end)from emp ;

案例:统计班级各个学员的成绩,展示的规则如下:
-- >= 85,展示优秀
-- >= 60,展示及格
-- 否则,展示不及格

先创建表并插入数据

create table score
(id int comment 'ID',name varchar(20) comment '姓名',math int comment'数学',english int comment'英语',chinese int comment '语文'
)comment'学员成绩表';
insert into score(id, name, math, english, chinese) VALUES(1,'Tom',67,88,95),(2,'Rose',23,66,90),(3,'Jack',56,98,76);

selectid,name,math,(case when math >=85 then '优秀' when math >=60 then '及格'else '不及格' end )'数学',english,(case when english >=85 then '优秀' when english >=60 then '及格'else '不及格' end )'英语',chinese,(case when chinese >=85 then '优秀' when chinese >=60 then '及格' else '不及格' end )'语文'from score;


二、约束

1、概念:约束是作用于表中字段上的规则,用于限制存储在表中的数据。

2、目的:保证数据库中数据的正确、有效性和完整性。

3、分类 

注意:约束是作用于表中字段上的,可以在创建表/修改表的时候添加约束
测试:

如图,我们创建该结构的表

测试:首先创建表并插入数据

-- 创建用户表
create table user
(id int primary key auto_increment comment '主键',name varchar(10) not null unique comment '姓名',age int check(age > 0 && age <= 120 ) comment '年龄',status char(1)  default '1' comment '状态',gender char(1) comment '性别'
)comment '用户表';-- 插入数据
insert into user(name,age,status,gender) values ('Tom1',19,'1','男'),('Tom2',15,'0','男'),('Tom3',22,'1','女');

或使用 datagrip创建

这里黄色钥匙表示主键 

然后我们测试各个约束:

insert into user(name,age,status,gender) values (null,19,'1','男');  #姓名not null,非空约束
insert into user(name,age,status,gender) values ('Tom1',19,'1','男'); #姓名unique,唯一约束insert into user(name,age,status,gender) values ('tmo4',122,'1','男') ; #年龄检查约束check
insert into user(name,age,status,gender) values ('tom5',50,'1','男'); #年龄检查约束checkinsert into user(name,age,gender) values ('tmo6',39,'男'); #没有输入status状态,默认值将赋1

4、外键约束

概念:外键用来让两张表的数据之间建立连接,从而保证数据的一致性和完整性

如我们下面2张表,虽然部门id代表的是同一个意思,但目前尚未创建联系,2者并无直接数据上的关联,因此当我们删除其中一个数据时,会造成另一个数据的不完整,无法保证数据完整性和一致性

子表:

父表: 

4.1添加外键的语法:

1、未创建表时,直接添加外键
CREATE TABLE 表名
(字段名	数据类型[CONSTRAINT][外键名称] FOREIGN KEY(外键字段名) REFERENCES 主表(主表列名)
)2、已经创建表,额外增加外键
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY(外键字段名) REFERENCES 主表(主表列名);

在datagrip中添加外键

alter table emp add constraint dept_id_fk foreign key (dept_id) references dept(id);

刷新后可以看到emp表的dept_id这里出现了蓝色的钥匙,即添加了外键 

 此时我们已经无法删除dept表里的1

 4.2删除外键:

ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;

 4.3更新/删除行为:

NO ACTION	当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。(与 RESTRICT一致)
RESTRICT	当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。(与 NO ACTION 一致
CASCADE		当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有,则也删除/更新外键在子表中的记录
SET NULL	当在父表中删除对应记录时,首先检查该记录是否有对应外键,如果有则设置子表中该外键值为1(这就要求该外键允许取nuI)
SET DEFAULT	父表有变更时,子表将外键列设置成一个默认的值(lnnodb不支持)

添加行为:即在添加外键时最后加上更新与删除的行为

ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY(外键字段名) REFERENCES 主表(主表列名) 
on update 行为 on delete 行为;

接下来我们对刚才的emp和dept表添加cascade行为

alter table emp add constraint dept_id_fk foreign key (dept_id) references dept(id) 
on update cascade on delete cascade ;

接下来,我将父表中的id1改为6

 

查看emp表,也变成6

 我再将父表中6删除

子表为6的数据全部删除

 还可以使用datagrip自带的modify table


 三、多表查询

1、多表关系

项目开发中,在进行数据库表结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结构,由于业务之间相互关联,所以各个表结构之间也存在着各种联系,基本上分为三种:

    一对多(多对一)

  • 案例:部门与员工的关系
  • 关系:一个部门对应多个员工,一个员工对应一个部门
  • 实现:在多的一方建立外键,指向一的一方的主键

    多对多

  • 案例:学生与课程的关系
  • 关系:一个学生可以选修多门课程,一门课程也可以供多个学生选择
  • 实现:建立第三张中间表,中间表至少包含两个外键,分别关联两方主键

    一对一

  • 案例:用户与用户详情的关系
  • 关系:一对一关系,多用于单表拆分,将一张表的基础字段放在一张表中,其他详情字段放在另一张表中,以提升操作效率
  • 实现:在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一的(UNIQUE)

2、多表查询概述

概述:指从多张表中查询数据

笛卡尔积:笛卡尔乘积是指在数学中,两个集合A集合和 B集合的所有组合情况。(在多表查询时,需要消除无效的笛卡尔积)

 分类:

  • 连接查询

    • 内连接:相当于查询A、B交集部分数据

    • 外连接:

      • 左外连接:查询左表所有数据,以及两张表交集部分数据
      • 右外连接:查询右表所有数据,以及两张表交集部分数据
  • 自连接:当前表与自身的连接查询,自连接必须使用表别名


接下来,我创建emp和dept和salgrade3个表,下面所有案例均使用这3个表进行

-- 插入数据
create table emp #员工表
(id int auto_increment comment 'ID' primary key,name varchar(50) not null comment '姓名',age int comment'年龄',job varchar(20) comment '职位',salary int comment '薪资',entrydate date comment '入职时间',managerid int comment '直属领导ID',dept_id int comment '部门ID'
)comment '员工表';insert into emp (id, name, age, job, salary, entrydate, managerid, dept_id)
values (1, '金庸', 66, '总裁', 20000, '	2000/1/1', null, 5),(2, '张无忌', 20, '项目经理', 12500, '	2005/12/5', 1, 1),(3, '杨逍', 33, '开发', 8400, '	2000/11/3', 2, 1),(4, '韦一笑', 48, '开发', 11000, '	2002/2/5', 2, 1),(5, '常遇春', 43, '开发', 10500, '	2004/9/7', 3, 1),(6, '小昭', 19, '	程序员鼓励师', 6600, '2004/10/12', 2, 1),(7, '灭绝', 60, '	财务总监', 8500, '2002/9/12', 1, 3),(8, '周芷若', 19, '会计', 48000, '	2006/6/2', 7, 3),(9, '丁敏君', 23, '出纳', 5250, '2009/5/13', 7, 3),(10, '赵敏', 20, '市场部总监', 12500, '	2004/10/12', 1, 2),(11, '鹿杖客', 56, '职员', 3750, '	2006/10/3', 10, 2),(12, '鹤笔翁', 19, '职员', 3750, '	2007/5/9', 10, 2),(13, '方东白', 19, '职员', 5500, '	2009/2/12', 10, 2),(14, '张三丰', 88, '销售总监', 14000, '	2004/10/12', 1, 4),(15, '俞莲舟', 38, '销售', 4600, '	2004/10/12', 14, 4),(16, '宋远桥', 40, '销售', 4600, '	2004/10/12', 14, 4),(17, '陈友谅', 42, 'null', 2000, '2011/10/12', 1, null);create table dept #部门表
(id  int auto_increment comment 'ID' primary key, #主键自增name varchar(50) not null comment '部门名称'
)comment'部门表';
insert into dept (id,name) VALUES (1,'研发部'),(2,'市场部'),(3,'财务部'),(4,'销售部'),(5,'总经办'),(6,'人事部');alter table emp add constraint dept_id_fk foreign key (dept_id) references dept(id);create table salgrade
(grade int,losal int, #最低薪资hisal int  #最高薪资
) comment '薪资等级表';insert into salgrade values (1, 0, 3000);
insert into salgrade values (2, 3001, 5000);
insert into salgrade values (3, 5001, 8000);
insert into salgrade values (4, 8001, 10000);
insert into salgrade values (5, 10001, 15000);
insert into salgrade values (6, 15001, 20000);
insert into salgrade values (7, 20001, 25000);
insert into salgrade values (8, 25001, 30000);

当我同时执行2个有约束作用的表时,2个有外键的数据将会以笛卡尔积的形式展示:

select *from emp,dept;

102=17*6

 解决:

select *from emp,dept where emp.dept_id = dept.id;


3、内连接

隐式内连接
SELECT 字段列表 FROM 表1,表2 WHERE 条件... ;显式内连接
SELECT 字段列表 FROM 表1 [INNER] JOIN 表2 0N 连接条件... ;

内连接查询的是两张表交集的部分,即绿色

案例:

-- 内连接演示
-- 1.查询每一个员工的姓名 , 及关联的部门的名称 (隐式内连接实现)
select emp.name,dept.name from emp,dept where emp.dept_id = dept.id;-- 2.查询每一个员工的姓名 , 及关联的部门的名称 (显式内连接实现)
select emp.name,dept.name from emp inner join dept on emp.dept_id = dept.id;

4、外连接

左外连接:
SELECT 字段列表 FROM 表1 LEFT [OUTER]JOIN 表2 0N 条件 ...;
相当于查询表1(左表)的所有数据 包含 表1和表2交集部分的数据右外连接:
SELECT 字段列表 FROM 表1 RIGHT [OUTER]OIN 表2 0N 条件 ...;
相当于查询表2(右表)的所有数据 包含 表1和表2交集部分的数据

即A或B+中间交集的区域

案例:

#外连接演示
-- 1.查询emp表的所有数据, 和对应的部门信息(左外连接)
select e.*,d.name from emp e left outer join dept d on d.id = e.dept_id;-- 2.查询dept表的所有数据,和对应的员工信息(右外连接)
select e.*,d.* from emp e right outer join dept d on d.id = e.dept_id;
-- 等价于
select e.*,d.* from dept d left outer join emp e on d.id = e.dept_id;

5、自连接

自连接查询语法:

SELECT 字段列表 FROM 表A 别名A JOIN 表A 别名B ON 条件 ...;

自连接查询,可以是内连接查询,也可以是外连接查询

案例:

-- 1.查询员工及其 所属领导的名宁
-- 内连接
select e.name '员工',em.name '所属领导' from emp e join emp em on e.managerid = em.id;
-- 或
select e.name '员工',em.name '所属领导' from emp e , emp em where e.managerid = em.id;-- 2.查询所有员工 emp 及其领导的名字 emp , 如果员工没有领导, 也需要查询出来
-- 使用外连接 完全显示所有员工,使用左外
select a.name '员工',b.name '所属领导' from emp a left outer join emp b on a.managerid = b.id;

6、联合查询    union / union all

对于union查询,就是把多次查询的结果合并起来,形成一个新的查询结果集。

SELECT 字段列表 FROM 表A ...
UNION [ALL]
SELECT 字段列表 FROM 表B ...;

案例: 

-- 1.将薪资低于 5000 的员工 ,和 年龄大于 50 岁的员工全部查询出来
select name from emp where salary < 5000
union all    #有重复
select name from emp where age > 50;select name from emp where salary < 5000
union
select name from emp where age > 50;

对于联合查询的多张表的列数必须保持一致,字段类型也需要保持一致

 Union all会将全部的数据直接合并在一起,Union会对合并之后的数据去重


7、子查询

概念:SQL语句中嵌套SELECT语句,称为嵌套查询,又称子查询

SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2 );

子查询外部的语句可以是INSERT / UPDATE / DELETE / SELECT 的任何一个

根据子查询结果不同,分为:

  • 标量 子查询(子查询结果为单个值)
    • 子查询返回的结果是单个值(数字、字符串、日期等),最简单的形式,这种子查询成为标量子查询
        常用的操作符:= <> > >= < <=
  • 列 子查询(子查询结果为一列)
  • 行 子查询(子查询结果为一行)
  • 表 子查询(子查询结果为多行多列)

根据子查询位置,分为:

  • WHERE之后
  • FROM之后
  • SELECT之后

①标量 子查询

子查询返回的结果是单个值(数字、字符串、日期等),最简单的形式,这种子查询成为标量子查询
    常用的操作符:= <> > >= < <=

案例:

-- 1。 查询 “销售部” 的所有员工信息
-- ① 查询”销售部“的部门id
select id from dept where name = '销售部';
-- ② 根据查询到的id查找emp里对应的员工
select *from emp where emp.dept_id = (select id from dept where name = '销售部');-- 2. 查询在 “方东白” 入职之后的员工信息
-- ① 查询”方东白“的入职时间
select entrydate from emp where name = '方东白';
-- ② 根据查询到的入职时间查找之后的员工
select *from emp where entrydate > (select entrydate from emp where name = '方东白');

②列 子查询

子查询返回的结果是一列(可以是多行),这种子查询称为列子查询
    常用的操作符:IN 、NOT IN 、ANY 、SOME、ALL

IN			在指定的集合范围之内,多选一
NOT IN		不在指定的集合范围之内
ANY			子查询返回列表中,有任意一个满足即可
SOME		与ANY等同,使用SOME的地方都可以使用ANY
ALL			子查询返回列表的所有值都必须满足

案例: 

-- 查询财务部id
select id from dept where name ='财务部';
-- 查询财务部的人员工资
select salary from emp where dept_id = (select id from dept where name ='财务部');
-- 查询比财务部的所有人员工资高的员工
select *from emp where salary > all(select salary from emp where dept_id = (select id from dept where name ='财务部'));-- 3. 查询比研发部其中 任意一人 工资高的员工信息
-- 查询研发部id
select id from dept where name ='研发部';
-- 查询研发部的人员工资
select salary from emp where dept_id = (select id from dept where name ='研发部');
-- 查询比研发部的任意人员工资高的员工
select *from emp where salary > any (select salary from emp where dept_id = (select id from dept where name ='研发部'));

③行 子查询

子查询返回的结果是一行(可以是多列),这种子查询称为行子查询
常用的操作符:=、<>、IN、NOT IN

案例:

-- 1. 查询与“张无忌”的薪资及直属领导相同的员工信息 ;
-- 查询张无忌的薪资和直属领导
select salary,managerid from emp where name= '张无忌';
-- 查询与张无忌薪资的直属领导相同的员工
select *from emp where salary = 12500 and managerid = '1';
-- 或使用以下形式:
select *from emp where (salary,managerid) = (12500,'1');
-- 修改为题意符合的
select *from emp where (salary,managerid) = (select salary,managerid from emp where name= '张无忌');

④表 子查询

子查询返回的结果是多行多列,类似一张表,这种子查询称为表子查询
常用的操作符:IN
表子查询的结果往往跟在from后面,作为一张临时表,再与其他表进行联查操作

案例:

-- 1. 查询与 “鹿杖客”、“宋远桥” 的职位和薪资相同的员工信息
-- 查询“鹿杖客”、“宋远桥” 的职位和薪资
select job,salary from emp where name= '鹿杖客' or name='宋远桥';
-- 查询与其相同的员工
select *from emp where (job,salary) = any (select job,salary from emp where name= '鹿杖客' or name='宋远桥');
-- 或
select *from emp where (job,salary) in (select job,salary from emp where name= '鹿杖客' or name='宋远桥');#       满足 任意一行一列-- 2. 查询入职日期是 “2006-01-01” 之后的员工信息,及其部门信息
-- 入职日期是 “2006-01-01” 之后的员工信息
select * from emp where entrydate > '2006-01-01';
-- 查询这部分员工,对应的部门信息;
select e.name,d.name from  (select * from emp where entrydate > '2006-01-01') e left outer join dept d on e.dept_id = d.id;#               将上面查询结果作为一张表                                            和另外一张表进行联查

8、多表查询案例

根据上面的学习与emp、dept和salgrade 3个表,实现11个案例:

-- 1、查询员工的姓名、年龄、职位、部门信息 (隐式内连接)
select emp.name, age, job, dept_id
from emp,dept
where emp.dept_id = dept.id;-- 2、查询年龄小于30岁的员工姓名、年龄、职位、部门信息。 (显式内连接)
select emp.name, age, job, dept_id
from empinner join dept d on emp.dept_id = d.id
where emp.age < 30;-- 3、查询拥有员工的部门ID、部门名称。 (即2表之间的交集部分,内连接)
select distinct d.id, d.name
from emp,dept d
where emp.dept_id = d.id;-- 4、查询所有年龄大于40岁的员工,及其归属的部门名称;如果员工没有分配部门,也需要展示出来(左外连接)
select e.name, d.name
from emp eleft join dept d on d.id = e.dept_id
where e.age > 40;-- 5、查询所有员工的工资等级。
select e.name, e.salary, s.losal, s.hisal, s.grade
from emp e,salgrade s
where e.salary >= s.losaland e.salary <= s.hisal;
-- 或使用between and
select e.name, e.salary, s.losal, s.hisal, s.grade
from emp e,salgrade s
where e.salary between s.losal and s.hisal;-- 6、查询“研发部”所有员工的信息及工资等级(隐式内连接)
-- 表:emp 、 dept 、 salgrade
-- 连接条件:e.salary between s.losal and s.hisal;  e.dept_id = d.id;
-- 查询条件:dept.name = '研发部';
select e.name, e.salary, s.losal, s.hisal, s.grade
from salgrade s,emp e,dept d
where (e.salary between s.losal and s.hisal)and e.dept_id = d.idand d.name = '研发部';-- 7、查询“研发部”员工的平均工资。(聚合函数)
-- 表:emp 、 dept
-- 连接条件:e.dept_id = d.id;
-- 查询条件:dept.name = '研发部';
select id from dept d where d.name = '研发部';
select avg(e.salary) from emp e where e.dept_id = (select id from dept d where d.name = '研发部');
-- 或
select avg(e.salary) from emp e, dept d
where e.dept_id = d.id and d.name = '研发部';-- 8、查询工资比“灭绝”高的员工信息(标量子查询)
select salary from emp where name = '灭绝';
select * from emp where salary > (select salary from emp where name = '灭绝');-- 9、查询比平均薪资高的员工信息
select avg(salary) from emp;
select * from emp where salary > (select avg(salary) from emp);-- 10.查询低于本部门平均工资的员工信息
-- 查询指定部门平均工资
select avg(e1.salary) from emp e1 where e1.dept_id = 1; #1号部门
select avg(e1.salary) from emp e1 where e1.dept_id = 2;
#2号部门
# ...
-- 查询低于本部门平均工资的员工信息
select *, (select avg(e1.salary) from emp e1 where e1.dept_id = e2.dept_id) '平均薪资'
from emp e2
where e2.salary < (select avg(e1.salary) from emp e1 where e1.dept_id = e2.dept_id);-- 11.查询所有的部门信息,并统计部门的员工人数。(子查询)
-- 查询各个部门信息
select d.id, d.name from dept d;
-- 查询不同部门的人数
select count(*) from emp e where e.dept_id = 1;
select count(*) from emp e where e.dept_id = 2;
-- 根据不同部门查询人数
select d.id, d.name, (select count(*) from emp e where e.dept_id = d.id) '人数'
from dept d;

最后再来3个表:student、student_course、course

create table student #学生表
(id   int auto_increment primary key comment '主键ID',name varchar(10) comment '姓名',no   varchar(10) comment '学号'
) comment '学生表';
insert into student
values (null, '黛货丝', '2000100101'),(null, '谢现', '2000100102'),(null, '正天', '2000100103'),(null, '韦-笑', '2000100104');
-- 多对多
create table course #课程表
(id   int auto_increment primary key comment '主键ID',name varchar(10) comment '课程名称'
) comment '课程表';
insert into course
values (null, 'Java'),(null, 'PHP'),(null, 'MySQL'),(null, 'Hadoop');create table student_course #中间表
(id        int auto_increment comment '主键' primary key,studentid int not null comment '学生ID',courseid  int not null comment '课程ID',constraint fk_courseid foreign key (courseid) references course (id),constraint fk_studentid foreign key (studentid) references student (id)
) comment '学生课程中间表';
insert into student_course
values (null, 1, 1),(null, 1, 2),(null, 1, 3),(null, 2, 2),(null, 2, 3),(null, 3, 4);

-- 12.查询所有学生的选课情况,展示出学生名称,学号,课程名称
-- 表:student、student_course、course
-- 连接条件:student.id = student_course.studentid; course.id=student_course.courseid;
select  s1.name,s1.no,c.name
from  student s1,student_course s2,course c
where s1.id = s2.studentid and c.id = s2.courseid;

四、事务

1、事务简介

事务 是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统
                                提交或撤销操作请求,即这些操作要么同时成功,要么同时失败

A在银行向B赚100元,一个正常的流程如下:

  1. 查询A账户余额是否有100元
  2. A账户余额-100元
  3. B账户余额+100元

如果在②之后如果程序出现异常,那么不能再向下③执行,则A已经-100,而B没有+100,数据出现问题

为了避免这种情况,那么就可以将这个流程控制在一个事务的范围内:

  1. start        开启事务
  2. 查询A账户余额是否有100元
  3. A账户余额-100元
  4. B账户余额+100元
  5. end        提交事务(2,3,4三步全部执行成功才提交)

如果在②之后如果程序出现异常,将进行回滚事务,即将②临时修改的数据恢复,这就保证了数据的完整性和一致性(即出现异常操作同时失败)

默认MySQL的事务是自动提交的,也就是说,当执行一条DML(数据操作语言)语句,MySQL会立即隐式的提交事务


2、事务操作

查看事务提交方式
SELECT @@autocommit ;  #为1则为自动,0为手动

组合1:修改事务提交方式

设置事务提交方式
SET @@autocommit = 0;  #设置为手动提交事务
COMMIT;回滚事务
ROLLBACK;

组合2:不修改事务提交方式

开启事务
START TRANSACTION 或 BEGIN提交事务
COMMIT;回滚事务
ROLLBACK;

 程序运行成功,执行commit,失败则回滚rollback


3、事务四大特性(ACID)

原子性(Atomicity): 	事务是不可分割的最小操作单元,要么全部成功,要么全部失败
一致性(Consistency): 事务完成时,必须使所有的数据都保持一致状态
隔离性 (Isolation):	数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行
持久性 (Durability): 事务一旦提交或回滚,它对数据库中的数据的改变就是永久的

4、并发事务问题

  • 脏读               一个事务读到另外一个事务还没有提交的数据。
  • 不可重复读    一个事务先后读取同一条记录,但两次读取的数据不同,称之为不可重复读。
  • 幻读              一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了“幻觉”

5、事务隔离级别

不同数据库的默认隔离级别不同,MySQL是RR,Oracle是RC

串行化:一次只允许一个事务操作,A事务操作时,B事务只有等A操作完成提交后才能操作

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

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

相关文章

工厂能源管控系统

随着现代工业的发展&#xff0c;工厂能源消耗不断增加&#xff0c;能源成本成为企业生产经营的重要组成部分。为了降低能源消耗、提高生产效率和降低成本&#xff0c;越来越多的企业开始采用工厂能源管控系统。本文将从多个方面介绍工厂能源管控系统的全面内容。 一、工厂能源管…

C# PaddleInference OCR 表格识别

效果 项目 VS2022.net4.8OpenCvSharp4Sdcb.PaddleInferenceSdcb.PaddleOCR 测试图片 代码 using OpenCvSharp.Extensions; using OpenCvSharp; using Sdcb.PaddleInference; using Sdcb.PaddleOCR; using Sdcb.PaddleOCR.Models; using Sdcb.PaddleOCR.Models.Details; using…

前端开发中的单例模式

在前端开发中&#xff0c;单例模式是一种常见的设计模式&#xff0c;用于确保一个类只有一个实例&#xff0c;并提供一个全局访问点来获取该实例。 在JavaScript中&#xff0c;可以使用以下几种方式来实现单例模式&#xff1a; 字面量方式&#xff1a; const singleton {// …

spring boot 集成dubbo

本demo使用spring boot 2.4.1版本集成 dubbo 2.7.15 1.创建maven项目及其子模块 父工程pom.xml <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation"http://maven.ap…

如何在海外进行A/B测试

A/B测试是对应用的各个版本进行实验&#xff0c;以分析用户如何与其交互的有效过程&#xff0c;它能够帮助我们改进关键指标&#xff0c;例如参与度或应用内购买&#xff0c;以及推出新功能&#xff0c;从而最大限度地降低大规模流失用户的风险。 A/B测试和ASO优化通常适用于应…

Android Jetpack Compose多平台用于Android和IOS

Android Jetpack Compose多平台用于Android和IOS JetBrains和外部开源贡献者已经努力工作了几年时间来开发Compose Multiplatform&#xff0c;并最近发布了适用于iOS的Alpha版本。自然地&#xff0c;我们对其功能进行了测试&#xff0c;并决定通过使用该框架在iOS上运行我们的…

分布式搜索--elasticsearch

一、初识 elasticsearch 1. 了解 ES ① elasticsearch 是一款非常强大的开源 搜索引擎&#xff0c;可以帮助我们从海量数据中 快速找到需要的内容 ② elasticsearch 结合 kibana、Logstash、 Beats&#xff0c;也就是 elastic stack (ELK)&#xff0c;被 广泛应用在日志数据分…

架构师日记-到底该如何搭建一个新系统 | 京东云技术团队

一 前言 架构设计按照实施过程可分为工程架构&#xff0c;业务架构&#xff0c;部署架构等多个维度&#xff0c;一个好的系统架构标准应该具备可扩展、可维护、可靠性、安全性和高性能等特点。尽管这些特点大家都熟知&#xff0c;但在实际落地时&#xff0c;我们更为迫切的想知…

pytorch线性模型 学习前要学习的基础知识

跟着刘二大人学pytorch&#xff0c;补全一下我的基础缺失 1.numpy基础 import numpy as np from PIL import Image anp.array([1,2,3]) #生成一维数组 print(a) bnp.arange(1,4)#创建等差数组&#xff0c;默认等差是1&#xff0c;数组为1&#xff0c;2&#xff0c;3&#xff0…

Efficient Methods for Non-stationary Online Learning

Dynamic regret Adaptive regret 假设&#xff1a; 算法过程&#xff1a; Regret分析

D. Pairs of Segments

Problem - D - Codeforces 思路&#xff1a;其实它求的就是不相交区间的最大数量&#xff0c;但是它的区间是两个区间合并得到&#xff0c;所以我们可以直接将所有能合并的区间直接合并&#xff0c;然后做一遍不相交区间的最大数量&#xff0c;这样存在一种问题就是一个区间会不…

SolidWorks二次开发-BOM球标和材料表

目标先到100&#xff0c;实在没什么好写的了&#xff0c;先把这两个简单的功能列一下吧。 private void btnInsertBalloon_Click(object sender, EventArgs e){//插入对应的BOM气泡球 球标//操作步骤->选中视图&#xff0c;执行自动球标命令SldWorks swApp Utility.Conne…