数据库基础的语法记忆

##################### DDL:数据定义语言,用来定义数据库对象(数据库,表,字段)######################

#################数据库操作
# 查询所有数据库
show databases ;
# 查询当前数据库
select database();
# 创建数据库并指定字符集
create database if not exists itcast default charset utf8mb4;
# 删除数据库
drop database if exists itcast;
# 切换数据库
use itcast;
select database();

#################表操作-查询创建
# 查询当前数据库所有表
show tables;
use db_userwallet;
show tables;
# 查看表结构
desc tb_userwallet;
# 查询指定表的建表语句
show create table tb_userwallet;
# 创建表结构:字符串使用'',最后一个字段不加逗号','
use itcast;
create table tb_user(
    id int comment '编号',
    name varchar(50) comment '姓名',
    age int comment '年龄',
    gender varchar(1) comment '性别'
)comment '用户表';
show tables ;
# 练习
create table emp(
    id int comment '编号',
    workNum varchar(10) comment '工号',
    name varchar(10) comment '姓名',
    gender char(1) comment '性别',
    age tinyint comment '年龄',
    idcard char(18) comment '身份证号',
    entrydate date comment '入职时间'
);
desc emp;
#################表操作-修改
# 添加字段
alter table emp add nickname varchar(20) comment '昵称';
desc emp;
# 修改数据类型
alter table emp modify nickname varchar(10);
desc emp;
# 修改字段名和字段类型
alter table emp change nickname username varchar(30) comment '昵称';
desc emp;
# 删除字段
alter table emp drop username;
desc emp;
# 修改表名
alter table emp rename to employee;
show tables ;
#################表操作-删除
# 删除表
drop table if exists tb_user;
show tables ;
# 删除指定表并重新创建表
# truncate table 表名

##################### DML:数据操作语言,用来对数据库中表的数据进行增删改操作######################

#################添加数据
# 给指定字段添加数据
insert into employee(id, workNum, name, gender, age, idcard, entrydate)
values (1,'1','Itcast','男','10','123456789123456789','2000-01-01');
select * from employee;
# 给全部字段添加数据
insert into employee values(2,'2','张无忌','男','18','123456789987654321','2005-01-01');
select * from employee;
# 批量添加数据
insert into employee values (3,'3','韦一笑','男','38','123456789937654321','2005-01-01'),
                            (4,'4','赵敏','女','18','123456789987654321','2005-01-01');
select * from employee;

#################修改数据
# 修改一个字段
update employee set name = 'itheima' where id = 1;
select * from employee;
# 修改多个字段
update employee set name = '小昭' ,gender = '女' where id = 1;
select * from employee;
# 全部修改
update employee set entrydate = '2008-01-01';
select * from employee;

#################删除数据
# 删除指定数据
delete from employee where gender = '女';
select * from employee;
# 删除全部
delete from employee;

##################### DQL:数据查询语句,用来查询数据库表中的数据########################
# 数据准备
drop table if exists emp;
create table emp(
                    id int comment '编号',
                    workno varchar(10) comment '工号',
                    name varchar(10) comment '姓名',
                    gender char(1) comment '性别',
                    age tinyint unsigned comment '年龄',
                    idcard char(18) comment '身份证号',
                    workaddress varchar(50) comment '工作地址',
                    entrydate date comment '入职时间'
)comment '员工表';
INSERT INTO emp (id, workno, name, gender, age, idcard, workaddress, entrydate)
VALUES (1, '00001', '柳岩666', '女', 20, '123456789012345678', '北京', '2000-01-01');
INSERT INTO emp (id, workno, name, gender, age, idcard, workaddress, entrydate)
VALUES (2, '00002', '张无忌', '男', 18, '123456789012345670', '北京', '2005-09-01');
INSERT INTO emp (id, workno, name, gender, age, idcard, workaddress, entrydate)
VALUES (3, '00003', '韦一笑', '男', 38, '123456789712345670', '上海', '2005-08-01');
INSERT INTO emp (id, workno, name, gender, age, idcard, workaddress, entrydate)
VALUES (4, '00004', '赵敏', '女', 18, '123456757123845670', '北京', '2009-12-01');
INSERT INTO emp (id, workno, name, gender, age, idcard, workaddress, entrydate)
VALUES (5, '00005', '小昭', '女', 16, '123456769012345678', '上海', '2007-07-01');
INSERT INTO emp (id, workno, name, gender, age, idcard, workaddress, entrydate)
VALUES (6, '00006', '杨逍', '男', 28, '12345678931234567X', '北京', '2006-01-01');
INSERT INTO emp (id, workno, name, gender, age, idcard, workaddress, entrydate)
VALUES (7, '00007', '范瑶', '男', 40, '123456789212345670', '北京', '2005-05-01');
INSERT INTO emp (id, workno, name, gender, age, idcard, workaddress, entrydate)
VALUES (8, '00008', '黛绮丝', '女', 38, '123456157123645670', '天津', '2015-05-01');
INSERT INTO emp (id, workno, name, gender, age, idcard, workaddress, entrydate)
VALUES (9, '00009', '范凉凉', '女', 45, '123156789012345678', '北京', '2010-04-01');
INSERT INTO emp (id, workno, name, gender, age, idcard, workaddress, entrydate)
VALUES (10, '00010', '陈友谅', '男', 53, '123456789012345670', '上海', '2011-01-01');
INSERT INTO emp (id, workno, name, gender, age, idcard, workaddress, entrydate)
VALUES (11, '00011', '张士诚', '男', 55, '123567897123465670', '江苏', '2015-05-01');
INSERT INTO emp (id, workno, name, gender, age, idcard, workaddress, entrydate)
VALUES (12, '00012', '常遇春', '男', 32, '123446757152345670', '北京', '2004-02-01');
INSERT INTO emp (id, workno, name, gender, age, idcard, workaddress, entrydate)
VALUES (13, '00013', '张三丰', '男', 88, '123656789012345678', '江苏', '2020-11-01');
INSERT INTO emp (id, workno, name, gender, age, idcard, workaddress, entrydate)
VALUES (14, '00014', '灭绝', '女', 65, '123456719012345670', '西安', '2019-05-01');
INSERT INTO emp (id, workno, name, gender, age, idcard, workaddress, entrydate)
VALUES (15, '00015', '胡青牛', '男', 70, '12345674971234567X', '西安', '2018-04-01');
INSERT INTO emp (id, workno, name, gender, age, idcard, workaddress, entrydate)
VALUES (16, '00016', '周芷若', '女', 18, null, '北京', '2012-06-01');
select * from emp;

#################基础查询
# 查询多个字段
select id,name,gender from emp;
#查询全部字段
select * from emp;
# 字段设置别名
select name as '姓名',gender as '性别' from emp;
# 去除重复记录
select distinct workaddress '工作地点' from emp;

#################条件查询
# 查询年龄等于88的员工
select * from emp where age = 88;
# 查询年龄小于20的员工
select * from emp where age < 20;
# 查询没有身份信息的员工
select * from emp where idcard is null;
# 查询有身份证号的员工
select * from emp where idcard is not null;
# 查询年龄不为88的员工
select * from emp where age != 88;
select * from emp where age <> 88;
# 查询年龄在15(包含)和20(包含)之间的员工
select * from emp where age >= 15 && age <= 20;
select * from emp where age >=15 and age <=20;
select * from emp where age between 15 and 20;
# 查询性别为女且年龄小于25的员工
select * from emp where gender = '女' and age < 25;
# 查询年龄等于18或20或40的员工
select * from emp where age = 18 or age = 20 or age = 40;
select * from emp where age in (18,20,40);
# 查询姓名为两个字的员工
select * from emp where name like '__';
# 查询身份证号最后是X的员工
select * from emp where idcard like '%X';
select * from emp where idcard like '_________________X';

#################聚合函数:将一列作为一个整体进行纵向计算
# 统计员工数目
select count(*) from emp;
# 统计idcard不为null的员工数目
select count(idcard) from emp;
# 统计该企业员工的平均年龄
select avg(age) from emp;
# 统计该企业员工最大年龄
select max(age) from emp;
# 统计该企业员工最小年龄
select min(age) '最小年龄' from emp;
# 统计西安地区员工的年龄之和
select sum(age) '西安地区年龄和' from emp where workaddress = '西安';

#################分组查询
# 根据性别分组,统计男女性员工的数量
select gender,count(*) from emp group by gender;
# 根据性别分组,统计男性员工和女性员工的平均年龄
select gender,avg(age) from emp group by gender;
# 查询年龄小于45的员工,并根据工作地点进行分组,获取员工数量大于等于3的工作地址
select workaddress,count(*) add_count from emp where age <45 group by workaddress having add_count>=3;
# 统计各个工作地址上班的男性即女性员工数量
select workaddress,gender,count(*) from emp group by gender, workaddress;

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

#################分页查询
# 查询第一页员工数据,每页显示10条数据
select * from emp limit 0,10;
select * from emp limit 10;
# 查询第二页的员工数据,每页显示10条数据,----->(页码-1)*每页记录数
select * from emp limit 10,10;

# 例题
# 查询年龄为20,21,22,23岁的员工数据
select * from emp where age in (20,21,22,23);
# 统计员工表中,年龄小于60岁的,男性员工和女性员工人数
select gender,count(*) from emp where age<60 group by gender;
# 查询所有年龄小于等于35的员工的姓名和年龄,并对查询结果进行按年龄升序排序,如果年龄相同则按照入职时间降序排序
select name,age from emp where age<35 order by age asc ,entrydate desc ;
# 查询性别为男,且年龄在20-40岁(包含)的前五个员工信息,对查询结果按照年龄升序排序,年龄相同按照入职时间降序排序
select * from emp where gender = '男' and age in(20,40) order by age asc ,entrydate desc limit 5;

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

##################### DCL:数据控制语句,用来管理数据库用户,控制数据库访问权限######################

#################管理用户
# 查询用户
select * from mysql.user;
# 创建用户:创建用户itcast,只能在当前主机访问,密码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';

#################权限控制
# 查询权限:查询'heima'@'%'的权限
show grants for 'heima'@'%';
# 授予权限:授予'heima'@'%'用户itcast数据库所有表的所有操作权限
grant all on itcast.* to 'heima'@'%';
# 撤销权限:撤销'heima'@'%'用户的itcast数据库所有权限
revoke all on itcast.* from 'heima'@'%';

#####################             函数               ######################
#################字符串函数
# concat:字符串拼接,不仅两个
select concat('hello','MySQL');
# lower:全部转小写
select lower('HELLO');
# upper:全部转大写
select upper('hello');
# lpad:左填充:在01左边填充-,知道字符串长度位5
select lpad('01',5,'-');
# rpad:右填充
select rpad('01',5,'-');
# trim:去除空格:去除字符串头部和尾部的空格
select trim(' hello world');
# substring:截取字符串,索引从1开始
select substring('hello mysql',1,5);

# 案例:对企业员工工号提出要求,统一为5位数,不足5位的在前面补0
update emp set workno = lpad(workno,5,'0');
select * from emp;

#################数值函数
# ceil:向上取整
select ceil(1.1);
# floor:向下取整
select floor(1.9);
# mod:取模
select mod(7,4);
# rand:获取随机数,获取0-1的随机数
select rand();
# round:四舍五入,保留2位小数
select round(2.344,2);

# 案例:通过数据库函数,生成一个六位随机验证码
select lpad(round(rand()*1000000,0),6,'0');

#################日期函数
# 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 70 year );
# datediff:获取两个日期相差的天数,前面减后面
select datediff('2021-10-01','2021-12-01');

#################流程函数
# if
select if(false,'ok','error');
# ifnull:如果value1不为空返回value1,否则返回value2
select ifnull('ok','default');
select ifnull('','default');
select ifnull(null,'default');
# case when then else end
# 需求:查询emp表的姓名员工和工作地址,(北京/上海->一线城市,其他->二线城市)
select
    name,
    (case workaddress when '北京' then '一线城市' when '上海' then '一线城市' else '二线城市' end) as '工作地点'
from emp;

#####################             约束               ######################
# 非空约束:NOT NULL
# 唯一约束:UNIQUE
# 主键约束:PRIMARY KEY
# 默认约束:DEFAULT
# 检查约束(8.0.16以后版本):CHECK
# 外键约束:FOREIGN KEY

# 演示:
CREATE TABLE tb_user(
                        id int AUTO_INCREMENT PRIMARY KEY COMMENT 'ID唯一标识',
                        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 '性别'
);
insert into tb_user(name,age,status,gender) values ('Tom1',19,'1','男'),
                                                   ('Tom2',25,'0','男');
insert into tb_user(name,age,status,gender) values ('Tom3',19,'1','男');
insert into tb_user(name,age,status,gender) values (null,19,'1','男');
insert into tb_user(name,age,status,gender) values ('Tom3',19,'1','男');
insert into tb_user(name,age,status,gender) values ('Tom4',80,'1','男');
insert into tb_user(name,age,status,gender) values ('Tom5',-1,'1','男');
insert into tb_user(name,age,status,gender) values ('Tom5',121,'1','男');
insert into tb_user(name,age,gender) values ('Tom5',120,'男');

#####################             外键约束               ######################
# 数据准备
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, '总经办');

drop table emp;
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-01-01', null,5),(2, '张无忌', 20,'项目经理',12500, '2005-12-05', 1,1),
    (3, '杨逍', 33, '开发', 8400,'2000-11-03', 2,1),(4, '韦一笑', 48, '开发',11000, '2002-02-05', 2,1),
    (5, '常遇春', 43, '开发',10500, '2004-09-07', 3,1),(6, '小昭', 19, '程序员鼓励师',6600, '2004-10-12', 2,1);

###################添加外键
# CREATE TABLE 表名(
#     字段名 数据类型,
#     ...
#     [CONSTRAINT] [外键名称] FOREIGN KEY (外键字段名) REFERENCES 主表 (主表列名)
# );

# ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名)REFERENCES 主表 (主表列名) ;

# 案例:为emp表的dept_id字段添加外键约束,关联dept表的主键id
alter table emp add constraint fk_emp_dept_id foreign key (dept_id) references dept(id);

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

#################### 删除/更新行为
# NO ACTION:当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不
#           允许删除/更新。 (与 RESTRICT 一致) 默认行为

# RESTRICT:当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不
#          允许删除/更新。 (与 NO ACTION 一致) 默认行为

# CASCADE:当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有,则
#         也删除/更新外键在子表中的记录

# SET NULL:当在父表中删除对应记录时,首先检查该记录是否有对应外键,如果有则设置子表
#          中该外键值为null(这就要求该外键允许取null)

# SET DEFAULT:父表有变更时,子表将外键列设置成一个默认的值 (Innodb不支持)

# 具体语法
# ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段) REFERENCES 主表名 (主表字段名)
# ON UPDATE CASCADE ON DELETE CASCADE;

# 演示:CASCADE
alter table emp add constraint fk_emp_dept_id foreign key (dept_id) references dept(id)
on update cascade on delete cascade ;

# 演示:SET NULL
alter table emp drop foreign key fk_emp_dept_id;
alter table emp add constraint fk_emp_dept_id foreign key (dept_id) references dept(id)
    on update set null on delete set null ;

################################# 多表查询 #########################
# 数据准备
drop table if exists dept;
drop table if exists emp;
-- 创建dept表,并插入数据
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, '人事部');

-- 创建emp表,并插入数据
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 '员工表';
-- 添加外键
alter table emp add constraint fk_emp_dept_id foreign key (dept_id) references dept(id);
INSERT INTO emp (id, name, age, job,salary, entrydate, managerid, dept_id)
VALUES
    (1, '金庸', 66, '总裁',20000, '2000-01-01', null,5),
    (2, '张无忌', 20, '项目经理',12500, '2005-12-05', 1,1),
    (3, '杨逍', 33, '开发', 8400,'2000-11-03', 2,1),
    (4, '韦一笑', 48, '开发',11000, '2002-02-05', 2,1),
    (5, '常遇春', 43, '开发',10500, '2004-09-07', 3,1),
    (6, '小昭', 19, '程序员鼓励师',6600, '2004-10-12', 2,1),
    (7, '灭绝', 60, '财务总监',8500, '2002-09-12', 1,3),
    (8, '周芷若', 19, '会计',48000, '2006-06-02', 7,3),
    (9, '丁敏君', 23, '出纳',5250, '2009-05-13', 7,3),
    (10, '赵敏', 20, '市场部总监',12500, '2004-10-12', 1,2),
    (11, '鹿杖客', 56, '职员',3750, '2006-10-03', 10,2),
    (12, '鹤笔翁', 19, '职员',3750, '2007-05-09', 10,2),
    (13, '方东白', 19, '职员',5500, '2009-02-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);

#  分类:
# 连接查询:
#     内连接:相当于A,B交集部分
#     外连接:
#         左外连接:查询左表所有数据,以及两表交集部分数据
#         右外连接:查询右表所有数据,以及两表交集部分数据
#     自连接:当前表与自生的连接查询,自链接必须使用表别名
# 子查询

###########################连接查询
############### 内连接
# 隐式内连接:查询每一过员工的姓名,及关联的部门的名称
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 e.name,d.name from emp e inner join dept d on e.dept_id = d.id;
select e.name,d.name from emp e join dept d on e.dept_id = d.id;

############### 外连接
# 左外连接:查询emp表中的所有数据,和对应的部门信息,子表为左表
select e.*,d.name from emp e left outer join dept d on e.dept_id = d.id;
select e.*,d.name from emp e left 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 d.*,e.* from dept d left outer join emp e on e.dept_id = d.id;

############## 自连接->既可以是内连接查询,也可以是外连接查询
# 查询员工及所属领导的名字
select a.name ,b.name from emp a,emp b where a.managerid = b.id;
# 查询所有员工及其领导的名字,如果员工每有领导,也需要查询出来
select a.name '员工',b.name '领导' from emp a left outer join emp b on a.managerid = b.id;

############## 联合查询:把多次查询结果合并起来,形成一个新的查询结果集
# SELECT 字段列表 FROM 表A ...
#         UNION [ ALL ]
# SELECT 字段列表 FROM 表B ....;
# 1.对于联合查询的多张表的列数必须保持一致,字段类型也需要保持一致。
# 2.union all 会将全部的数据直接合并在一起,union 会对合并之后的数据去重

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

###########################子查询: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 = '销售部';
# 2.更具查询销售部门id,查询员工信息
select * from emp where dept_id = (select id from dept where name = '销售部');

##################列子查询
# 常用的操作符:IN 、NOT IN 、 ANY 、SOME 、 ALL
# 查询销售部和市场部的所有员工信息
# 1.查询销售部和市场部的部门id
select id from dept where name = '销售部' or name = '市场部';
# 2.根据部门id,查询员工信息
select * from emp where dept_id in (select id from dept where name = '销售部' or name = '市场部');

# 行子查询
# 常用的操作符:= 、<> 、IN 、NOT IN
# 查询与张无忌的薪资及直属领导相同的员工信息
# 1.查询张无忌的薪资及直属领导
select salary,managerid from emp where name = '张无忌';
# 2.查询张无忌的薪资及直属领导相同的员工信息
select * from emp where (salary,managerid) = (select salary,managerid from emp where name = '张无忌');

# 表子查询
# 常用的操作符:IN
# 查询与 "鹿杖客" , "宋远桥" 的职位和薪资相同的员工信息
# 1.查询 "鹿杖客" , "宋远桥" 的职位和薪资
select job, salary from emp where name = '鹿杖客' or name = '宋远桥';
# 2.查询与 "鹿杖客" , "宋远桥" 的职位和薪资相同的员工信息
select * from emp where (job,salary) in ( select job, salary from emp where name ='鹿杖客' or name = '宋远桥' );

###########################         事务        ################################
# 数据准备
drop table if exists account;
create table account(
                        id int primary key AUTO_INCREMENT comment 'ID',
                        name varchar(10) comment '姓名',
                        money double(10,2) comment '余额'
) comment '账户表';
insert into account(name, money) VALUES ('张三',2000), ('李四',2000);

#############控制事务一
# 查看/设置事务提交方式
select @@autocommit;
set @@autocommit = 0;
set @@autocommit = 1;
# 提交事务
commit ;
# 回滚事务
rollback;

#############控制事务二
# 开启事务
start transaction or begin;
# 提交事务
commit ;
# 回滚事务
rollback ;

# 转账案例
# 开启事务
start transaction;
# 查询张三余额
select * from account where name = '张三';
# 张三余额减少1000
update account set money = money-1000 where name = '张三';
# 李四余额增加1000
update account set money = money+1000 where name = '李四';
# 如果正常执行完毕,提交事务
commit ;
# 如果出现报错
# rollback ;

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

########事务并发问题
# 脏读:一个事务读到了另一个事务还没有提交的数据
# 不可重复读:一个事务先后读取同一条数据,但两次数据不同,称之为不可重复读
# 幻读:一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时候,又发现这行数据以及存在,好像出现了幻影

########事务隔离级别
# 隔离级别                      脏读           不可重复读       幻读
# Read uncommitted              1               1            1
# Read committed                0               1            1
# Repeatable Read(默认)          0               0            1
# Serializable                  0               0            0

# 查看事务隔离级别
select @@transaction_isolation;

# 设置事务隔离级别
# set SET [ SESSION | GLOBAL ] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED |READ COMMITTED | REPEATABLE READ | SERIALIZABLE }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值