首页 > 数据库 >【MySQL】基础部分——DDL,DML,DQL,DCL,函数,约数,多表查询,事务

【MySQL】基础部分——DDL,DML,DQL,DCL,函数,约数,多表查询,事务

时间:2024-09-15 15:19:48浏览次数:12  
标签:约数 DCL 多表 name 查询 emp where id select

个人学习记录,供以后回顾和复习

ubuntu下安装使用

参考文章:传送
进入mysql用命令 mysq -u root -p(密码)
注意p和密码之间没有空格

1.DDL,DML,DQL,DCL

在这里插入图片描述

sql可以单行或者多行,以分号结尾,可以用空格和缩进来增强可读性,也不区分大小写 。
单行注释:-- 内容,或者# 内容
多行注释:/* 内容 */

DDL

数据库

show databases;
select database();
create database 数据库名;
create database [if not exists] 数据库名 [default charset 字符集] [collate 排序规则];#不存在某某数据库,就创建
drop database [if exists] 数据库名;
use 数据库名;

实操:
每一个sql语句都要写分号,不然系统默认还没结束只是转行
create database itheima default charset utf8mb4;
创建itheima数据库,默认是utf8mb4的字符集,尽量不用utf8,因为他只有3个字节。

show tables;#先用use
desc 表名;
show create table 表名;#查询指定标的建表语句
#表的创建
create table 表名{
	字段1 字段1类型{comment 字段1注释},
	字段2 字段2类型{comment 字段2注释},
	....
	字段n 字段n类型{comment 字段n注释}
}{comment 表注释};

创建表举例:
eg1在这里插入图片描述
eg2
在这里插入图片描述

表的修改以及删除:

alter table 表名 add 字段名 类型(长度) [comment 注释] [约束];#添加字段
alter table 表名 modify 字段名 新数据类型(长度);#修改数据类型
alter table  表名 change 旧字段名 新字段名 类型(长度) [comment 注释] [约束];#修改字
段名和字段类型
alter table 表名 drop 字段名 # 删除字段名
alter table  表名 rename(to) 新表名 # 修改表名,可以不加to也能修改
drop table [if exists] 表名;#删除表
truncate table 表名;#清空表
create table new_table_name select * from old_table_name; # 复制表结构及数据
#复制表结构到新表,不复制数据
create table new_table_name select * from old_table_name where 1 = 2;
#或
create table new_table_name like old_table_name;

操作:

#添加一行nickname到emp表中
alter table emp add nickname varchar(20) comment '昵称';
#修改nickname字段名以及他的类型
alter table emp change nickname username varchar(30) comment '用户名';
#删除字段
alter table emp drop username
#更改表名
alter tale emp rename to employee
#删除表
drop table if exists tb_user;
#清空表
truncate table employee;

DML

主要是对数据记录的增删改

1.给指定字段添加数据
insert into 表名(字段名1, 字段名2, ......) values (值1, 值2, ......);

insert into employee(id, workno, name, gender, age, idcard, entrydate)
VALUES (1, '1', 'Itcast', '男', 10, '123412341234123412', '2022-09-18');
2.未指定字段名,则是给全部字段添加数据
insert into 表名 values(值1,值2,...);

insert into employee values (2, '2', 'Itcast', '男', 10,
'123412348234123412', '2022-09-17');
3.批量添加
#不想一段一段来,一次性添加多段
insert into employee values (....), (.....).....;
#模仿2,后面跟着多段,用逗号分开

#修改id为1的数据,将name改为itheima
update employee set name = 'itheima' where id = 1;
#修改id为1的数据,将name改为小昭,gender改为女
update employee set name = '小昭',gender = '女'  where id = 1;
#所有员工入职日期改为2008-01-01
update employee set entrydate = '2008-01-01';

delete from 表名 where 条件

delete from employee where gender = '女';
delete from employee;

DQL

顺序:select->from->where->group by->having->order by->limit

基本查询:select,from
条件查询:where,having
聚合函数:count,max,min,avg,sum(null不会参与)
分组查询:group by
排序查询:order by
分页查询:limit

条件查询

关键字含义
>,>=,<,<=,=大于,大于等于,小于,小于等于,等于
<>,!=不等于
between…and在某个范围之内(中间最小、and后大值)
in(…)在in之后的列表中的值,多选一
like占位符,模糊匹配,_匹配单个字符,&匹配任意个
is null是null
and或&&并且
or或II或者
not或者!不是
select * from 'order'; # 关键字重名时使用
select * from emp where age in (15, 20, 70); # age = 15 or age = 20 or age = 70是一个意思
select * from emp where name like '__';#两个下划线
select * from emp where idcard like '%x';#身份证号最后一位是x的员工信息

分组查询

select 字段列表 from 表名 where 条件 group by 分组字段名 havin 分组后过滤条件
where不能对聚合函数进行判断,而having可以!

  1. 执行顺序:where > 聚合函数 > having
  2. 分组之后,查询的字段一般为聚合函数和分组字段,查询其他字段无任何意义。
#根据性别分组,统计男员工和女员工的数量
select gender,count(*) from emp group by gender
#根据性别分组,统计男性员工和女性员工的平均年龄
select gender,avg(age) from emp group by gender
#查询年龄小于45的员工,并根据工作地址分组,获取员工数量大于等于3的工作地址
select workaddress,count(*) from where age < 45 group by workaddress having count(*) >= 3;

排序查询

select 字段列表 from 表名 order by 字段1 排序方式1 字段2 排序方式2
支持多字段排序!
asc升序(默认),desc降序

#根据年龄对公司的员工进行升序排序
select * from emp order by age asc;
#根据年龄对公司的员工进行升序排序,年龄相同,再按照入职时间进行降序排序
select * from emp order by age asc,entrydate desc;

分页查询

select 字段列表 from 表名 limit 起始索引,查询记录数
起始索引从0开始,
起始索引=(查询页码-1)*每页显示记录数

#查询第1页的员工数据,每页展示10条
select * from emp limit 0,10;
#查询第2页的员工数据,每页展示10条记录
select * from emp limit 10,10;

案例练习

1.查询年龄为20,21,22,23岁的员工信息
select * from emp where gender = '女' and age in(20, 21, 22, 23);
2.查询性别为男,并且年龄在20-40岁以内的姓名为三个字的员工
select * from emp where gender = '男' and age between 20 and 40 and name like '___';
3.统计员工表中,年龄小于60的,男性员工和女性员工的人数
select gender, count(*) from emp where age < 60 group by gender
4.查询所有年龄小于等于35岁员工的姓名和年龄,并对查询结果按年龄升序排序,如果年龄相同按入职时间降序排序
select name, age from emp where age <= 35 order by age asc, entrydate desc;
5.查询所有性别为男,且年龄在20-40内的前5个员工信息,对查询结果按照年龄升序排序,年龄相同的按照入职时间降序排序
select * from emp where gender = ‘男’ and age between 20 and 40 order by age asc, entrydate desc limit 5;

DQL执行顺序:from->where->group by->select->order by->limit
所以在from中给表起了别名的话,在后序中可以直接使用别名

select name,age from emp e where age > 15 order by age asc;

DCL

用来管理数据库 用户、控制数据库访问权限

管理用户

1. 查询用户
use mysql;
select * from user;

2. 创建用户
create user '用户名'@'主机名' identified by '密码';

3. 修改用户密码
alter user '用户名'@'主机名' identified with mysql_native_password by '新密码';

4. 删除用户
drop user '用户名'@'主机名';

具体操作:

# 创建用户itcast,只能够在当前主机localhost访问,密码123456
create user 'itcast'@'localhost' identified by '123456';
# 创建用户heima,可以在任意主机访问该数据库,密码123456
create user 'heima'@'%' identified by '123456';
# 修改用户heima的访问密码为1234
alter user 'heima'@'%' identified with mysql_native_password by '1234';
# 删除itcast@localhost用户
drop user 'itcast'@'localhost';

权限控制

在这里插入图片描述

1. 查询权限
show grants for '用户名'@'主机名';

2. 授予权限
grant 权限列表 on 数据库名.表名 to '用户名'@'主机名';

3. 撤销权限
revoke 权限列表 on 数据库名.表名 from '用户名'@'主机名';

具体操作:

#查询权限
show grants for 'heima'@'%';
#授予权限
grant all on itcast.* to 'heima'@'%';
#撤销权限
revoke all on itcast.* from 'heima'@'%';

tips:
多个权限之间,使用逗号进行分隔
授权时,数据库名和表名可以使用*进行通配,代表所有

2.函数

字符串函数

在这里插入图片描述
演示:

select concat('Hello','MySQL');#HelloMySQL
select lower('Hello');#hello
select upper('Hello');#HELLO
select lpad('01',5,'-');#---01
select rpad('01',5,'-');#01---
select trim(' Hello MySQL ');#Hello MySQL
select substring('Hello MySQL',1,5)#Hello

操作:

#由于业务需求变更,企业员工的工号,统一为5位数,目前不足5位数的全部在前面补0
update emp from workno = lpad(workno,5,‘0’);

数值函数

在这里插入图片描述
演示:

select ceil(1.1)#2
select floor(1.9)#1
select mod(3,4)#3
select rand()#0~1之间的随机数
select round(2.345,2)#2.35

实操:

#根据数据库的函数,生成一个六位数的随机验证码
select lpad(round(rand() * 1000000,0),6,‘0’)
#0~1之间的数字小数点移6位
#保留0个小数
#lpad在不足的情况下前面补0

日期函数

在这里插入图片描述
演示:

select curdate();#本机获取当前日期
select curtime();#本机获取当前时间
select now();#年月日时分秒
select year(now())
select month(now())
select day(now())
select date_add(now(),interval 70 day) #当前时间往后推70天
select datediff('2021-12-01','2021-11-01')#30

实操:

#查询所有员工入职天数,并根据入职天数倒序排列
select name,datediff(curdate(),entrydate) as 'entrydays' from emp order by entrydays desc;

流程函数

在这里插入图片描述
演示:

select if(true,'OK','ERROR')#OK
select ifnull('OK','Default')#OK,' '也可以返回,只有null不返回

操作:

1.
# 查询emp表的员工姓名和工作地址(北京---->一线城市,其他---->二线城市)
select 
	name, 
	(case workaddress when '北京' then '一线城市' when '上海' then '一线城市' else '二线城市' end) as '工作地址'
from emp;

2.
# 统计班级各个学员的成绩,展示的规则如下:
# >= 85展示优秀;>=60展示及格;否则展示不及格
select
	id,
	name,
	case when math >= 85 then '优秀' when math >= 60 then '及格' else '不及格' end) '数学',
	case when english >= 85 then '优秀' when english >= 60 then '及格' else '不及格' end) '英语',
	case when chinese >= 85 then '优秀' when chinese >= 60 then '及格' else '不及格' end) '语文'
from score;

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', 25, '0', '男');
insert into user(name, age, status, gender) values('Tom3', 19, '1', '男');

结果:
在这里插入图片描述
外键用来让两张表的数据之间建立连接,从而保证数据的一致性和完整性。

1.添加外键
#方式1
create table 表名(
	字段名 数据类型,
	....
	[constraint] [外键名称] foreign key(外键字段名) references 主表(主表列名)
);
#方式2
alter table 表名 add constraint 外键名称 foreign key(外键字段名) references 主表(主表列名);

2.删除外键
alter table emp drop foreign key fk_emp_dept_id;

外键的删除/更新行为:
在这里插入图片描述

#on update在更新时怎么操作,on delete在删除时怎么操作
alter table 表名 add constraint 外键名称 foreign key (外键字段) references 主表名(主表字段名) on update cascade on delete cascade;

4.多表查询

多表关系

一对多:部门和员工,一个员工属于一个部门,一个部门有多个员工;

  • 在多的一方建立外键,指向一的一方。

多对多:学生与课程,一个学生可以选择多门课,一门课可以被多个学生选择

  • 建立一张中间表,至少包含两个外键,分别关联两方主键
#中间表
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 '学生课程中间表';

结果:
在这里插入图片描述

一对一:用户对用户。多用于单表拆分,将一张表的基础字段放在一张表中,其他详情字段放在另一张表中,以提升操作效率。

  • 在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一的UNIQUE
# 有一个单表users
CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL,
    email VARCHAR(100),
    phone VARCHAR(15),
    address VARCHAR(255),
    bio TEXT
);

users 存储了用户的基本信息(username,email)和详情信息(phone,address,bio),现在决定将这个表拆分成两个表:

  1. users_basic表,存储用户的基本信息。
  2. users_details表,存储用户的详细信息。
#创建基本信息表
CREATE TABLE users_basic (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL,
    email VARCHAR(100)
);
#创建详细信息表
CREATE TABLE users_details (
    user_id INT PRIMARY KEY,
    phone VARCHAR(15),
    address VARCHAR(255),
    bio TEXT,
    FOREIGN KEY (user_id) REFERENCES users_basic(id)
);

users_details表中的user_id字段是外键,引用了users_basic表中的id字段,从而建立一对一的关系,每个用户在 users_basic 表和 users_details 表中只能有一条对应记录。

#进行多表查询
SELECT 
    b.id, 
    b.username, 
    b.email, 
    d.phone, 
    d.address, 
    d.bio
FROM 
    users_basic b
LEFT JOIN 
    users_details d 
ON 
    b.id = d.user_id;

通过 LEFT JOIN,我们可以查询出 users_basic 和 users_details 表中的对应信息,这样实现了将单表拆分为多表后的数据获取。

内连接

查询的是两张表交集的数据:

  • 隐式内连接

select 字段列表 from 表1,表2 where 条件…

#查询每个员工的姓名,以及关联的部门的名称(隐式内连接实现)
#表结构 emp,dept
#连接条件 emp.dept_id == dept.id
select emp.name,dept.name from emp,dept where emp.dept_id = dept.id;
select e.name,d.name from emp e,dept d where e.dept_id = d.id;
  • 显示内连接

select 字段列表 from 表1 [inner] join 表2 on 连接条件

#查询每个员工的姓名,以及关联的部门的名称(隐式内连接实现)
#表结构 emp,dept
#连接条件 emp.dept_id == dept.id
select e.name,d.name from emp e inner join dept d on e.dept_id = d.id;

外连接

  • 左外连接

查询左表的所有数据,包含表1和表2交集部分的数据
select 字段列表 from 表1 left [outer] join 表2 on 条件…

  • 右外连接

查询右表的所有数据,包含表1和表2交集部分的数据
select 字段列表 from 表1 right [outer] join 表2 on 条件…

外连接演示:

#查询emp表的所有数据,和对应部门信息(左外连接)
select e.*,d.name from emp e left outer join dept d on e.dept_id = d.id;

#查询dept表的所有数据,和对应的员工信息(右外连接)
select d.*,e.* from emp e right outer join dept d on e.dept_id = d.id;

自连接

自连接查询语法:
select 字段列表 from 表A 别名A join 表A 别名B on 条件…
演示:

  1. 查询员工 及其 所属领导的名字

在这里插入图片描述
emp表中有id,name,managerid,其中managerid的id指的是领导的id,领导id对应的name就是领导的name

所以不要把这个表看做一个表,同一个表看做两个表,一个是员工表,一个是领导表,员工表的managerid对应的就是领导表的主键id

select a.name,b.name from emp a,emp b where a.managerid = b.id;

联合查询union

对于union查询,就是把多次查询的结果合并起来,形成一个新的查询结果集
语法:
select 字段列表 from 表A
union[all]
select 字段列表 from 表B

其中:对于联合查询的多张表的列数必须保持一致,字段类型也需要保持一致!union all 会将全部的数据直接合并在一起,union 会对合并后的数据去重。

# 将薪资低于5000的员工,和年龄大于50岁的员工全部查询出来
select * from emp where salary < 5000 
union all
select * from emp where age > 50

union 和 or 的区别:如果某一行同时满足 salary < 5000 和 age > 50,or 的话,它会返回一次;而union all合并多个查询的结果集,而不会去除重复的行。如果某一行满足两个条件,则会返回多次(因为 UNION ALL 不去重)。如果使用union也想去重的话,可以只写union,不写all

子查询

sql中嵌套select语句,称为嵌套查询,又称子查询。比如:在这里插入图片描述
子查询外部的语句可以是insert/update/delete/select的任何一个。

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

  • 标量子查询,子查询结果为单个值
  • 列子查询,子查询结果为一列
  • 行子查询,子查询结果为一行
  • 表子查询,子查询结果为多行多列

标量子查询

返回的是单个值,最简单形式

查询销售部的所有员工信息:

a.首先要查销售部id
select id from dept where name = '销售部';#4
b.然后根据销售部部门id查询员工信息
select * from emp where dept_id = 4;

a+b:
select * from emp where dept_id = (select id from dept where name = '销售部');

列子查询

返回的是一列,也可以是多行

查询销售部和市场部的所有员工信息

a. 查询销售部和市场部的id
select id from dept where name = '销售部' or name = '市场部';#2,4
b. 根据部门id,查询员工信息
select * from emp where dept_id in (2,4);

a+b:
select * from emp where dept_id in (select id from dept where name = '销售部' or name = '市场部');

查询比财务部所有人工资都高的员工信息

a. 查询比财务部所有人工资都高的员工信息
select salary from emp where dept_id = (select id from dept where name = '财务部');
b. 比财务部所有人工资都高的员工信息
select * from emp where salary > all (select salary from emp where dept_id = (select id from dept where name = '财务部'));

比研发部其中任意一人工资高的员工信息

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

上面的any也可以换成some,效果一样

行子查询

可以是一行多列

查询与张无忌的薪资及直属领导相同的员工信息

a. 查询张无忌的薪资及其直属领导
select salary,managerid from emp where name = '张无忌';#12500,1
b. 查询与张无忌的薪资及直属领导相同的员工信息
select * from emp where salary = 12500 and managerid = 1;

a+b:
select * from emp where (salary,managerid) = (select salary,managerid from emp where name = '张无忌')

表子查询

返回多行多列

查询与鹿杖客,宋远桥的职位和薪资相同的员工信息

a. 查询鹿杖客,宋远桥的职位和薪资
select job,salary from emp where name = '鹿杖客' or name = '宋远桥';
b. 查询鹿杖客,宋远桥的职位和薪资相同的员工信息
select * from emp (job,salary) in (select job,salary from emp where name = '鹿杖客' or name = '宋远桥');

查询入职日期是2006-01-01之后的员工信息,及其部门信息

a. 入职日期是2006-01-01之后的员工信息
select * from emp where entrydate > '2006-01-01';
b. 查询这部分员工,对应的部门信息
select * from (select * from emp where entrydate > '2006-01-01') e left join dept d on e.dept_id = d.id;

案例学习

主要涉及emp表,dept表,还有一个salgrade表,
emp与dept的关系,以及salgrade表:
在这里插入图片描述
salgrade表是薪资等级表,里面有薪资等级grade字段,等级对应的最低薪资losal字段,等级对应的最高薪资hisal字段

  1. 查询员工的姓名,年龄,职位,部门信息

涉及到员工的部门,就会涉及到两个表的连接查询,这个地方涉及的是隐式内连接

select e.name,e.age,e.job,d.name from emp e,dept d where e.dept_id = d.id;
  1. 查询年龄小于30的员工姓名,年龄,职位,部门信息

显示内连接

select e.name,e.age,e.job,d.name from emp e inner join dept d on e.dept_id = d.id where e.age < 30;
  1. 查询拥有员工的部门id,部门名称

去重!

select distinct d.id,d.name from emp e,dept d where e.dept_id = d.id;
  1. 查询所有年龄大于40岁的员工,及其归属的部门名称;如果员工没有分配部门,也需要展示出来
select * from emp e left join dept d on e.dept_id = d.id where e.age > 40;
  1. 查询所有员工的工作等级

emp与salgrade之间没有外键关联,但emp中有salary,从salgrade中通过hisal和losal推测

select e.*,s.grade from emp e,salgrade s where e.salary between s.losal and s.hisal;
  1. 查询研发部所有员工的信息以及工资等级

涉及了3张表emp,salgrade,dept
连接条件:emp.salary between salgrade.losal and salgrade.hisal,emp.dept_id = dept.id
查询条件:dept.name = ‘研发部’

select e.*,s.grade from emp e,dept d,salgrade s where e.dept_id = d.id and (e.salary between s.losal and s.hisal) and (d.name = '研发部');
  1. 查询研发部员工的平均工资

涉及到2张表

select avg(e.salary) from emp e,dept d where e.dept_id = d.id and d.name = '研发部';
  1. 查询工作比“灭绝”高的员工信息
select * from emp where salary > (select salary from emp where name = '灭绝');
  1. 查询比平均薪资高的员工信息
select * from emp where salary > (select avg(salary) from emp);
  1. 查询低于本部门平均工资的员工信息

查询指定部门的平均薪资:select avg(e1.salary) from emp e1 where e1.dept_id = 1;
查询本部门:一张表变成两张就行,当前部门的平均工资用e1来计算,查询的员工用e2表

select * from emp e2 where e2.salary < (select avg(e1.salary) from emp e1 where e1.dept_id = e2.dept_id);
  1. 查询所有的部门信息,并统计部门的员工人数

统计指定部门的员工数量:select count(*) from emp where dept_id = 1
查看部门的人数信息:select d.id,d.name,(select count(*) from emp e where e.dept_id = d.id) '人数' from dept d

select d.id,d.name,(select count(*) from emp e where e.dept_id = d.id) '人数' from dept d;
  1. 查询所有学生的选课情况,展示出学生名称,学号,课程名称
    在这里插入图片描述
    涉及表:student,course,student_course
    连接条件:student.id = student_course.studentid,course.id = student_course.courseid
select s.name,s.no,c.name from student s,student_course sc,course c where s.id = sc.studentid and sc.courseid = c.id;

5.事务

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

事务操作

转账操作(张三给李四转账1000)

1. 查询张三账户余额
select * from account where name = '张三';
2. 将张三账户余额-1000
update account set money = money - 1000 where name = '张三';
3. 将李四账户余额+1000
update account set money = money + 1000 where name = '李四';

123都是事物,是自动执行的,如果中间有异常,就会失败,所以需要考虑改变事物的方式:

# 方式一
#查看事务提交方式
SELECT @@AUTOCOMMIT;
#设置事务提交方式,1为自动提交,0为手动提交,该设置只对当前会话有效
SET @@AUTOCOMMIT = 0;
#此时为手动提交

#提交事务
COMMIT;
#一开始没执行提交时是没有反应的,执行了提交,才会有下一步

#一旦出错
#回滚事务
ROLLBACK;

方式1:给转账操作添加手动事务

select @@autocommit;# 1
set @@autocommit = 0;

---转账操作
1. 查询张三账户余额
select * from account where name = '张三';
2. 将张三账户余额-1000
update account set money = money - 1000 where name = '张三';
3. 将李四账户余额+1000
update account set money = money + 1000 where name = '李四';

---提交事务
commit;
---回滚事务
rollback;

方式2
开启事务

start transaction 或 begin;

提交事务

commit;

回滚事务

rollback;

自动提交的事务方式:

set @@autocommit = 1;
#自动提交
select @@autocommit;
#开启事务
start transaction;

---转账操作
1. 查询张三账户余额
select * from account where name = '张三';
2. 将张三账户余额-1000
update account set money = money - 1000 where name = '张三';
3. 将李四账户余额+1000
update account set money = money + 1000 where name = '李四';

---提交事务
commit;
---回滚事务
rollback;

事务四大特性

这里涉及面试题:原子性;一致性;隔离性;持久性

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

并发事务问题

A事务和B事务同时操作数据库会引发的问题
在这里插入图片描述

事务隔离级别

用来解决并发事务问题的
在这里插入图片描述
4种事务的隔离级别,×是在这种级别下可以解决

---查看事务隔离级别
select @@transaction_isolation;
---设置事务隔离级别
set [session|global] transaction isolation level {read uncommitted|read committed|repeatable read|serializable}

演示一下:

---查询事务隔离级别
select @@transaction_isolation;# repeatable read
---设置事务隔离级别
set session transaction isolation level read uncommitted;
set session transaction isolation level repeatable read;

开启2个终端窗口,相当于2个事务,切换到同一个数据库,演示第一个脏读问题:
窗口A:
设置了事务隔离级别是read uncommitted,它可以出现脏读问题
在这里插入图片描述
窗口B:
给张三减了1000
在这里插入图片描述
接下来看看窗口A:
张三的钱从2000减到了1000
在这里插入图片描述
以上就是脏读,因为窗口B执行的操作根本没有提交,事务开启了,它commit了吗?没有!所以read uncommitted是可以出现脏读问题的!
接下来将事务的隔离级别改成read committed
在这里插入图片描述
接下来脏读问题就会消失

标签:约数,DCL,多表,name,查询,emp,where,id,select
From: https://blog.csdn.net/weixin_45962681/article/details/142107843

相关文章

  • mysql笔记8(多表查询)
    文章目录1.union联合查询可能会用到去重操作2.innerjoin内连接3.leftjoin左连接4.rightjoin右连接5.crossjoin交叉连接6.naturaljoin自然连接naturalleftjoin自然左连接naturalrightjoin自然右连接自然连接的两张表没有同名字段怎么办?7.using......
  • mybatis plus多表查询的扩展
    mybatisplus提供了简单的CURD操作,但是有时我们的业务需要要求进行多表查询,这个时候,我们就需要加入多表查询的扩展了。 mybatis-plus-join,基于mybatis-plus的所有优点,然后还支持连表查询,还支持一对多,一对一的查询。mybatis-plus-join是mybatisplus的一个多表插件,上手简单,几分钟就......
  • WordCloud.top - 在线终极词云创建!
    WordCloud是您轻松制作令人着迷的文字云的终极工具。它非常适合营销人员、教育工作者、数据爱好者和创意专业人士,为您的视觉叙事需求提供无与伦比的多功能性和创造力!官网https://wordcloud.top/在线编辑器https://studio.wordcloudmaster.com/说明在哪里使用WordCloud?•营销活动:......
  • Python爬虫案例七:抓取南京公交信息数据并将其保存成excel多表形式
    测试链接:        https://nanjing.8684.cn/line4 思路:先抓取某个类型下的某一条线路所有数据,然后实现批量,,列举出三个类型代表既可源码:fromlxmlimportetreefromxlutils.copyimportcopyimportrequests,os,xlrd,xlwtdefget_all():#获取所......
  • P3327 [SDOI2015] 约数个数和
    [SDOI2015]约数个数和题目描述设\(d(x)\)为\(x\)的约数个数,给定\(n,m\),求\[\sum_{i=1}^n\sum_{j=1}^md(ij)\]输入格式输入文件包含多组测试数据。第一行,一个整数\(T\),表示测试数据的组数。接下来的\(T\)行,每行两个整数\(n,m\)。输出格式\(T\)行,每行一个整数,表......
  • 多表单验证
    <scriptsetuplang="ts">import{ref}from'vue';import{Modal,message}from'ant-design-vue';import{AIRPLANE_MISSION_MODE}from'../enum';importtype{deviceAirPortLoad}from'./columns'......
  • MySQL多表查询优化
    一、多表查询连接的选择:相信这内连接,左连接什么的大家都比较熟悉了,当然还有左外连接什么的,基本用不上我就不说了。然后要告诉大家的是,需要根据查询的情况,想好使用哪种连接方式效率更高。二、MySQL的JOIN实现原理在MySQL中,只有一种Join算法,就是大名鼎鼎的NestedLoopJoin,他没......
  • 【开源dcluster】一站式数据服务分析平台IDEA本地开发指南
    源码Gitee地址:https://gitee.com/zhenglv123456/dcluster在线文档:http://47.121.127.33:8090/在线体验:http://36.155.14.171:12345/dolphinscheduler/ui/login账号密码:test/test123  源码启动1.前端启动 进入dolphinscheduler-ui目录,执行以下命令 npmins......
  • 【重学 MySQL】二十四、笛卡尔积的错误和正确的多表查询
    【重学MySQL】二十四、笛卡尔积的错误和正确的多表查询笛卡尔积的理解和错误笛卡尔积的理解定义例子在数据库中的应用总结笛卡尔积的错误正确的多表查询使用INNERJOIN使用WHERE子句(隐式内连接)总结在数据库查询中,特别是涉及到多表查询时,理解笛卡尔......
  • 初级练习[4]:多表查询——表联结
    目录多表查询:表联结示例 查询有两门以上的课程不及格的同学的学号及其平均成绩 查询所有学生的学号、姓名、选课数、总成绩 查询平均成绩大于85的所有学生的学号、姓名和平均成绩 查询学生的选课情况:学号,姓名,课程号,课程名称 查询出每门课程的及格人数和不及格人数......