数据库
1:约束的概念
2:约束的分类
约束名称 | 描述 | 关键字 |
---|---|---|
非空约束 | 保证列中所有数据不能有null值 | NOT NULL |
唯一约束 | 保证列中所有数据各不相同 | UNIQUE |
主键约束 | 主键是一行数据的唯一标识,要求非空且唯一 | PRIMARY KEY |
检查约束 | 保证列中的值满足某一条件 | CHECK |
默认约束 | 保存数据时,未指定值则采用默认值 | DEFAULT |
外键约束 | 外键用来让两个表的数据之间建立链接,保证数据的唯一性和完整性 | FOREIGN KEY |
Tips:MySQL不支持检查约束
案例:根据需求,为表添加合适的约束(emp)
-- 员工表
CREATE TABLE emp (
id INT, -- 员工id,主键且自增长
ename VARCHAR(50), -- 员工姓名,非空且唯一
joindate DATE, -- 入职日期,非空
salary DOUBLE(7,2), -- 工资,非空
bonus DOUBLE(7,2) -- 奖金,如果没有奖金默认为0
);
-- 员工表
create table emp (
id int primary key auto_increment, -- 员工id,主键且自增长
ename varchar(50) not null unique, -- 员工姓名,非空并且唯一
joindate date not null, -- 入职日期,非空
salary double(7,2) not null, -- 工资,非空
bonus double(7,2) default 0 -- 奖金,如果没有奖金默认为0
);
1:概念
2:语法
(1)添加约束
-- 创建表时添加非空约束
CREATE TABLE 表名(
列名 数据类型 NOT NULL,
…
);
-- 建完表后添加非空约束
ALTER TABLE 表名 MODIFY 字段名 数据类型 NOT NULL;
(2)删除约束
ALTER TABLE 表名 MODIFY 字段名 数据类型;
1:概念
2:语法
(1)添加约束
-- 创建表时添加唯一约束
CREATE TABLE 表名(
列名 数据类型 UNIQUE [AUTO_INCREMENT],
-- AUTO_INCREMENT:当不指定值时自动增长
…
);
CREATE TABLE 表名(
列名 数据类型,
…
[CONSTRAINT] [约束名称] UNIQUE(列名)
);
-- 建完表后添加非空约束
ALTER TABLE 表名 MODIFY 字段名 数据类型 UNIQUE;
(2)删除约束
ALTER TABLE 表名 DROP INDEX 字段名;
1:概念
2:语法
(1)添加约束
-- 创建表时添加主键约束
CREATE TABLE 表名(
列名 数据类型 PRIMARY KEY [AUTO_INCREMENT]
…
);
CREATE TABLE 表名(
列名 数据类型,
[CONSTRAINT] [约束名称] PRIMARY KEY(列名)
);
-- 建完表后添加主键约束
ALTER TABLE 表名 ADD PRIMARY KEY(字段名);
(2)删除约束
ALTER TABLE 表名 DROP PRIMARY KEY;
1:概念
2:语法
(1)添加约束
-- 创建表时添加默认约束
CREATE TABLE 表名(
列名 数据类型 DEFAULT 默认值,
…
);
-- 建完表后添加默认约束
ALTER TABLE 表名 ALTER 列名 SET DEFAULT 默认值;
(2)删除约束
ALTER TABLE 表名 ALTER 列名 DROP DEFAULT;
1:概念
emp 员工表
id | name | age | dep_id |
---|---|---|---|
1 | 张三 | 20 | 1 |
2 | 李四 | 20 | 1 |
3 | 王五 | 20 | 1 |
4 | 赵六 | 20 | 2 |
5 | 孙七 | 22 | 2 |
6 | 周八 | 18 | 2 |
dept 部门表
id | dep_name | addr |
---|---|---|
1 | 研发部 | 广州 |
2 | 销售部 | 深圳 |
2:语法
(1)添加约束
-- 创建表时添加外键约束
CREATE TABLE 表名(
列名 数据类型,
…
[CONSTRAINT] [外键名称] FOREIGN KEY(外键列名) REFERENCES 主表(主表列名)
);
-- 建完表后添加外键约束
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主表列名称);
(2)删除约束
ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;
drop table if exists emp;
-- 员工表
create table emp (
id int primary key auto_increment, -- 员工id,主键且自增长
ename varchar(50) not null unique, -- 员工姓名,非空并且唯一
joindate date not null, -- 入职日期,非空
salary double(7,2) not null, -- 工资,非空
bonus double(7,2) default 0 -- 奖金,如果没有奖金默认为0
);
select * from emp;
insert into emp(id,ename,joindate,salary,bonus) values(1,'张三','1999-11-11',8000,5000);
-- 演示主键约束:非空且唯一 (员工id)
insert into emp(id,ename,joindate,salary,bonus) values(null,'张三','1999-11-11',8000,5000);
insert into emp(id,ename,joindate,salary,bonus) values(1,'张三','1999-11-11',8000,5000);
insert into emp(id,ename,joindate,salary,bonus) values(2,'李四','1999-11-11',8000,5000);
-- 演示非空约束 (员工姓名)
insert into emp(id,ename,joindate,salary,bonus) values(3,null,'1999-11-11',8000,5000);
-- 演示唯一约束 (员工姓名)
insert into emp(id,ename,joindate,salary,bonus) values(3,'李四','1999-11-11',8000,5000);
-- 演示默认约束 (奖金)bonus也不要写了
delete from emp;
insert into emp(id,ename,joindate,salary) values(3,'王五','1999-11-11',8000);
insert into emp(id,ename,joindate,salary,bonus) values(4,'赵6','1999-11-11',8000,null);
-- 演示自动增长:auto_increment:当列是 数学类型 并且 唯一约束
insert into emp(ename,joindate,salary,bonus) values('赵6','1999-11-11',8800,null);
insert into emp(id,ename,joindate,salary,bonus) values(null,'赵62','1999-11-11',8800,null);
insert into emp(id,ename,joindate,salary,bonus) values(null,'赵63','1999-11-11',8800,null);
select * from emp;
drop table if exists dept;
drop table if exists emp;
-- 部门表
CREATE TABLE dept (
did int primary key auto_increment,
dep_name varchar(20),
addr varchar(20)
);
-- 员工表
CREATE TABLE emp (
id int primary key auto_increment,
name varchar(20),
age int,
dep_id int,
-- 添加外键 dep_id,关联 dept 表的 id 主键
constraint fk_emp_dept foreign key(dep_id) references dept(did)
);
2:数据库设计概念
3:数据库设计的步骤
4: 表关系
一对多(多对一):
如:部门 和 员工
一个部门对应多个员工,一个员工对应一个部门
多对多
如:商品 和 订单
一个商品对应多个订单,一个订单包含多个商品
一对一:
如:用户 和 用户详情
一对一关系多用于表拆分,将一个实体中经常使用的字段放一张表,不经常使用的字段放另一张表,用于提升查询性能
一对多(多对一):
如:部门 和 员工
一个部门对应多个员工,一个员工对应一个部门
实现方式:在多的一方建立外键,指向一的一方的主键
tb_emp 员工表 M
id | name | age |
---|---|---|
1 | 张三 | 23 |
2 | 李四 | 24 |
3 | 王五 | 25 |
tb_dept 部门表 1
id | name | addr |
---|---|---|
1 | 财务部 | 北京 |
2 | 市场部 | 上海 |
3 | 研发部 | 成都 |
如:订单 和 商品
一个商品对应多个订单,一个订单包含多个商品
tb_order 订单表 M
id | payment | payment_type | status |
---|---|---|---|
1 | 7376.00 | 微信支付 | 未付款 |
2 | 59880.00 | 支付宝支付 | 已付款 |
tb_goods 商品表 M
id | title | price |
---|---|---|
1 | 华为P40手机 | 5988 |
2 | 海天酱油 | 9.9 |
3 | 华为GT2手表 | 1388 |
tb_order_goods 订单商品中间表
id | order_id | goods_id | count |
---|---|---|---|
1 | 1 | 1 | 1 |
2 | 1 | 3 | 1 |
3 | 2 | 1 | 10 |
/*
多对多:
如:订单 和 商品
一个商品对应多个订单,一个订单包含多个商品
实现方式:建立第三张中间表,中间表至少包含两个外键,分别关联两方主键
*/
-- 删除表
drop table if exists tb_order_goods;
drop table if exists tb_order;
drop table if exists tb_goods;
-- 订单表
create table tb_order (
id int primary key auto_increment,
payment double(10,2),
payment_type tinyint,
status tinyint
);
-- 商品表
create table tb_goods (
id int primary key auto_increment,
title varchar(100),
price double(10,2)
);
-- 订单商品中间表
create table tb_order_goods (
id int primary key auto_increment,
order_id int,
goods_id int,
count int
);
-- 建完表后,添加外键
alter table tb_order_goods add constraint fk_order_id foreign key(order_id) references tb_order(id);
alter table tb_order_goods add constraint fk_goods_id foreign key(goods_id) references tb_goods(id);
select * from tb_order;
select * from tb_goods;
select * from tb_order_goods;
如:用户 和 用户详情
一对一关系多用于表拆分,将一个实体中经常使用的字段放一张表,不经常使用的字段放另一张表,用于提升查询性能
tb_user 用户表
id | photo | nickname | age | gendar | city | edu | income | status | desc |
---|---|---|---|---|---|---|---|---|---|
1 | a.jpg | 一场梦 | 23 | 女 | 广州 | 硕士 | 3000 | 单身 | … |
2 | b.png | 风清扬 | 35 | 男 | 湖北 | 本科 | 30000 | 离异 | … |
3 | c.jpg | 赵云 | 41 | 男 | 河南 | 本科 | 40000 | 单身 | … |
tb_user 用户表 1
id | photo | nickname | age | gendar | desc_id |
---|---|---|---|---|---|
1 | a.jpg | 一场梦 | 23 | 女 | 1 |
2 | b.png | 风清扬 | 35 | 男 | 2 |
3 | c.jpg | 赵云 | 41 | 男 | 3 |
tb_user_desc 用户详情表 1
id | city | edu | income | status | desc |
---|---|---|---|---|---|
1 | 广州 | 硕士 | 3000 | 单身 | … |
2 | 湖北 | 本科 | 30000 | 离异 | … |
3 | 河南 | 本科 | 40000 | 单身 | … |
drop table if exists tb_user;
drop table if exists tb_user_desc
select * from tb_user;
select * from tb_user_desc;
-- tb_user_desc 用户详情表
create table tb_user_desc (
id int primary key auto_increment,
city varchar(20) not null,
edu varchar(20) not null,
income double(7,2) default 0,
status varchar(20),
descc varchar(20)
);
-- tb_user 用户表
create table tb_user (
id int primary key auto_increment,
photo varchar(20) not null,
nickname varchar(20) not null unique,
age int not null,
gendar varchar(20),
desc_id int unique,
constraint fk_user_desc foreign key(desc_id) references tb_user_desc(id)
);
-- tb_user 添加数据
insert into tb_user(id,photo,nickname,age,gendar) values
(1,'a.jpg','一场梦',23,'女'),
(2,'b.png','风清扬',35,'男'),
(3,'c.jpg','赵云',41,'男');
-- tb_user_desc 添加数据
insert into tb_user_desc(id,city,edu,income,statu,descs) values
(1,'广州','硕士',3000,'单身','...'),
(2,'湖北','本科',30000,'离异','...'),
(3,'河南','本科',40000,'单身','...');
1:多表查询简介
笛卡尔积:取A,B集合的所有组合情况
多表查询:从多张表查询数据
连接查询:
内连接:相当于查询A,B交集数据
外连接:
左外连接:相当于查询A表所有数据和交集部分数据
右外连接:相当于查询B表所有数据和交集部分数据
子查询
2:内连接
-- 隐式内连接
SELECT 字段列表 FROM 表1,表2… WHERE 条件;
-- 显式内连接
SELECT 字段列表 FROM 表1 [INNER] JOIN 表2 ON 条件;
内连接相当于查询A B 交集数据
3:外连接
-- 左外连接
SELECT 字段列表 FROM 表1 LEFT [OUTER] JOIN 表2 ON 条件;
-- 右外连接
SELECT 字段列表 FROM 表1 RIGHT [OUTER] JOIN 表2 ON 条件;
4:子查询
子查询概念:查询中嵌套查询,称嵌套查询为子查询
子查询根据查询结果不同,作用不同:
单行单列:作为条件值,使用 = != > < 等进行条件判断
SELECT 字段列表 FROM 表 WHERE 字段名 = (子查询);
多行单列:作为条件值,使用in等关键字进行条件判断
SELECT 字段列表 FROM 表 WHERE 字段名 in (子查询);
多行多列:作为虚拟表
SELECT 字段列表 FROM (子查询) WHERE 条件;
drop table if exists dept;
drop table if exists emp;
-- 部门表
CREATE TABLE dept (
did int primary key auto_increment,
dep_name varchar(20),
addr varchar(20)
);
-- 员工表
CREATE TABLE emp (
id int primary key auto_increment,
name varchar(20),
age int,
dep_id int,
-- 添加外键 dep_id,关联 dept 表的 id 主键
constraint fk_emp_dept foreign key(dep_id) references dept(did)
);
-- 添加两个部门
insert into dept(did,dep_name,addr) values(1,'研发部','广州'),(2,'销售部','深圳'),(3,'市场部','北京');
-- 添加员工,dep_id 表示员工所在的部门
insert into emp(id,name,age,dep_id) values
(1,'张三',20,1),
(2,'李四',20,1),
(3,'王五',20,1),
(4,'赵六',20,2),
(5,'孙七',22,2),
(6,'周八',18,2),
(7,'阿九',18,null);
-- -------------------------
select * from emp;
select * from dept;
-- 删除外键
alter table emp drop foreign key fk_emp_dept;
-- 建完表之后添加外键
alter table emp add constraint fk_emp_dept foreign key(dep_id) references dept(did);
-- 多表查询
select * from emp , dept;
-- 笛卡尔积:有 A,B两个集合,取A,B所有的组合情况
-- 消除无效数据
-- 查询emp 和 dept 的数据,emp.dep_id = dep.id
-- 隐式内连接
select * from emp , dept where emp.dep_id = dept.did;
-- 查询 emp 的 name , gender , dept 表的 dep_name
select emp.name,emp.age,dept.dep_name from emp , dept where emp.dep_id = dept.did;
-- 给表起别名
select t1.name,t1.age,t2.dep_name from emp t1 , dept t2 where t1.dep_id = t2.did;
-- 显式内连接
select * from emp inner join dept on emp.dep_id = dept.did;
-- inner可省略
select * from emp join dept on emp.dep_id = dept.did;
-- 外连接
select * from emp;
select * from dept;
-- 左外连接
-- 查询emp表所有数据和对应的部门信息
select * from emp left outer join dept on emp.dep_id = dept.did;
-- 右外连接
-- 查询dept表所有数据和对应的员工信息
select * from emp right outer join dept on emp.dep_id = dept.did;
select * from dept left outer join emp on emp.dep_id = dept.did; -- 左外连接也可做右外连接的事,把两个表名换过来就可以了
-- 嵌套查询
-- 查询年龄大于张三的员工信息
select * from emp;
select * from dept;
-- 1.查询张三的年龄
select age from emp where name = '张三';
-- 2.查询年龄高于张三的员工信息
select * from emp where age > 20;
-- 单行单列
select * from emp where age > (select age from emp where name = '张三');
-- 多行单列
-- 查询 '研发部' 和 '销售部'所有员工信息
select did from dept where dep_name = '研发部' or dep_name = '销售部';
select * from emp where dep_id in (1,2);
select * from emp where dep_id in (select did from dept where dep_name = '研发部' or dep_name = '销售部');
-- 查询 '研发部'的员工信息
select did from dept where dep_name = '研发部';
select * from emp where dep_id = 1;
select * from emp where dep_id = (select did from dept where dep_name = '研发部');
-- 多行多列
-- 查询年龄大于19岁的员工信息和部门信息
-- 查询年龄大于19岁的员工的员工信息
select * from emp where age > 19;
select * from (select * from emp where age > 19) t1, dept where t1.dep_id = dept.did;
5:多表查询案例 表(emp1、dept1、job、salarygrade)查询(job)
drop table if exists emp1;
drop table if exists dept1;
drop table if exists job;
drop table if exists salarygrade;
-- 部门表
create table dept1 (
id int primary key primary key, -- 部门id
dname varchar(50), -- 部门名称
loc varchar(50) -- 部门所在地
);
-- 职务表,职务名称,职务描述
create table job (
id int primary key, -- 员工id
jname varchar(20),
description varchar(50)
);
-- 员工表
create table emp1 (
id int primary key, -- 员工id
ename varchar(50), -- 员工姓名
job_id int, -- 职务id
mgr int, -- 上级领导
joindate date, -- 入职日期
salary decimal(7,2), -- 工资
bonus decimal(7,2), -- 奖金
dept1_id int, -- 所在部门编号
constraint emp1_jobid_ref_job_id_fk foreign key (job_id) references job (id),
constraint emp1_deptid_ref_dept1_id_fk foreign key (dept1_id) references dept1 (id)
);
-- 工资等级表
create table salarygrade (
grade int primary key, -- 级别
losalary int, -- 最低工资
hisalary int -- 最高工资
);
-- 添加4个部门
insert into dept1(id,dname,loc) values
(10,'教研部','北京'),
(20,'学工部','上海'),
(30,'销售部','广州'),
(40,'账务部','深圳');
-- 添加4个职务
insert into job (id,jname,description) values
(1,'董事长','管理整个公司,接单'),
(2,'经理','管理部门员工'),
(3,'销售员','向客人推销产品'),
(4,'文员','使用办公软件');
-- 添加员工
insert into emp1(id,ename,job_id,mgr,joindate,salary,bonus,dept1_id) values
(1001,'孙悟空',4,1004,'2002-12-17','8000.00',null,20),
(1002,'卢俊义',3,1006,'2001-02-20','16000.00','3000.00',30),
(1003,'林冲',3,1006,'2001-02-22','12500.00','5000.00',30),
(1004,'唐僧',2,1009,'2001-04-02','29750.00',null,20),
(1005,'李逵',4,1006,'2001-09-28','12500.00','14000.00',30),
(1006,'宋江',2,1009,'2001-05-01','25800.00',null,30),
(1007,'刘备',2,1009,'2001-09-01','24500.00',null,10),
(1008,'猪八戒',4,1004,'2007-04-19','30000.00',null,20),
(1009,'罗贯中',1,null,'2001-11-17','50000.00',null,10),
(1010,'吴用',3,1006,'2001-09-08','15000.00','0.00',30),
(1011,'沙僧',4,1004,'2007-05-23','11000.00',null,20),
(1012,'李逵',4,1006,'2001-12-03','9500.00',null,30),
(1013,'小白龙',4,1004,'2001-12-03','30000.00',null,20),
(1014,'关羽',4,1007,'2002-01-23','13000.00',null,10);
-- 添加5个工资等级
insert into salarygrade (grade,losalary,hisalary) values
(1,7000,12000),
(2,12010,14000),
(3,14010,20000),
(4,20010,30000),
(5,30010,99990);
select * from emp1;
select * from dept1;
select * from job;
select * from salarygrade;
-- 1.查询所有员工信息。查询员工编号,员工姓名,工资,职务名称,职称描述
/*
分析:
1.员工编号,员工姓名,工资 信息在 empq 员工表中
2.职务名称,职务描述 信息在 job 职务表中
3.job 职务表 和 emp1 员工表 是 一双多的关系 emp1.job_id = job.id
*/
-- 隐式内连接
select emp1.id, emp1.ename, emp1.salary, job.jname, job.description from emp1 , job where emp1.job_id = job.id;
select * from emp1;
select * from job;
-- 显式内连接
select emp1.id, emp1.ename, emp1.salary, job.jname, job.description from emp1 inner join job on emp1.job_id = job.id;
-- 2.查询员工编号,员工姓名,工资,职务名称,职务描述,部门名称,部门位置
/*
分析:
1.员工编号,员工姓名,工资 信息在 empq 员工表中
2.职务名称,职务描述 信息在 job 职务表中
3.job 职务表 和 emp1 员工表 是 一对多的关系 emp1.job_id = job.id
4.部门名称,部门位置 来自于 部门表 dept1
5.dept1 和 emp1 一对多的关系 dept1.id = emp.dept_id
*/
-- 隐式内连接
SELECT
emp1.id,
emp1.ename,
emp1.salary,
job.jname,
job.description,
dept1.dname,
dept1.loc
FROM
emp1,
job,
dept1
WHERE
emp1.job_id = job.id
AND emp1.dept1_id = dept1.id;
select * from emp1;
select * from job;
select * from dept1;
-- 显式内连接
SELECT
emp1.id,
emp1.ename,
emp1.salary,
job.jname,
job.description,
dept1.dname,
dept1.loc
FROM
emp1
INNER JOIN job ON emp1.job_id = job.id
inner join dept1 on emp1.dept1_id = dept1.id;
-- 3.查询员工姓名,工资,工资等级
/*
分析:
1.员工姓名,工资 信息在 emp1 员工表中
2.工资等级 信息在 salarygrade 工资等级表
3.emp1.salary >= salarygrade.losalary and emp1.salary <= salagrade.hisalary
*/
select emp1.ename, emp1.salary, t2.grade from emp1, salarygrade t2 where emp1.salary >= t2.losalary and emp1.salary <= t2.hisalary;
select emp1.ename, emp1.salary, t2.* from emp1, salarygrade t2 where emp1.salary >= t2.losalary and emp1.salary <= t2.hisalary;
select emp1.ename, emp1.salary, t2.grade from emp1, salarygrade t2 where emp1.salary between t2.losalary and t2.hisalary;
-- 4.查询员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级
/*
分析:
1.员工姓名,工资 信息在 emp1 员工表中
2.职务名称,职务描述 信息在 job 职务表中
3.job 职务表 和 emp1 员工表 是 一对多的关系 emp1.job_id = job.id
4.部门名称,部门位置 来自于 部门表 dept1
5.dept1 和 emp1 一对多的关系 dept1.id = emp.dept_id
6.工资等级 信息在 salarygrade 工资等级表
7.emp1.salary >= salarygrade.losalary and emp1.salary <= salagrade.hisalary
*/
SELECT
emp1.id,
emp1.ename,
emp1.salary,
job.jname,
job.description,
dept1.dname,
dept1.loc,
t2.grade
FROM
emp1
INNER JOIN job ON emp1.job_id = job.id
INNER JOIN dept1 ON emp1.dept1_id = dept1.id
INNER JOIN salarygrade t2 ON emp1.salary BETWEEN t2.losalary
AND t2.hisalary;
-- 5.查询出部门编号,部门名称,部门位置,部门人数
/*
分析:
1.部门编号、部门名称、部门位置 来自于部门 dept 表
2.部门人数:在emp1表中 按照dept1_id 进行分组,然后count(*)统计数据
3.使用子查询,让部门表和分组后的表进行内连接
*/
select * from dept1;
select dept1_id, count(*) from emp1 group by dept1_id ;
SELECT
dept1.id,
dept1.dname,
dept1.loc,
t1.count
FROM
dept1,(
SELECT
dept1_id,
count(*) count
FROM
emp1
GROUP BY
dept1_id
) t1
WHERE
dept1.id = t1.dept1_id;
1:事务简介
id | name | money |
---|---|---|
1 | 张三 | 1000 |
2 | 李四 | 1000 |
例子:张三向李四借500元,一个表记录,张三、李四的钱,两个各1000,怎么完成转账的操作呢,
查询李四帐户余额
李四帐户余额-500
张三帐户余额+500
出现异常,李四-500,张三余额没有+500,这种操作明显不合理,怎么预防这个问题呢
就要用到今天学的 事务 了。事务是一组命令,要么同时成功,要么同时失败,金钱总数不变
转账操作之前,开启事务,执行成功之后,提交事务,出现异常,则回滚事务
开启事务就是打一个标记,告诉数据库,这后面的执行是一些临时更改,例如说,给李四账户-500,它不真正的去把你整个数据库改了,它是一个临时的修改,
只有当你遇到了提交事务之后,才会真正的持久化的把这个表的数据改掉,
那么将来但凡有哪个地方呢,出现了异常,它就回滚事务,回滚事务就是撤销之前的临时操作,回滚到你开启事务之前的那个状态,
也就是张三,李四两个人的金钱不变的那个状态
2:事务操作表(account) 查询(account、anotheraccount)
-- 开启事务
START TRANSACTION;
或者 BEGIN;
-- 提交事务
COMMIT;
-- 回滚事务
ROLLBACK;
3:事务四大特征(非常常见的一个面试题)
(两个窗口,两个窗口其实就是对应着将来的两个事务,那么这两个事务之间的数据是否操作可见,那么就是我们据说的隔离性。隔离性越强,那么操作越不可见的,那么它的性能也就越低。一般不改变隔离性,用默认的,默认的就是我们在MySQL里边,当别人提交了或者回滚了,我才能看到对应对方的一个修改)
(也就是意味着在事务操作的过程中开启了事务,操作的过程中都是一些临时的改变,那么只有当你提交或者回滚才会真正的把这个操作的数据给它写到硬盘的文件上,落盘了之后持久化)
MySQL事务默认自动提交
-- 查看事务的默认提交方式
SELECT @@autocommit;
-- 1 自动提交 0 手动提交
set @@autocommit = 0;
将来用来Oracle,它的事务默认是手动提交的,也就是意味着将来你在写Oracle的SQL的时候,你一定记得commit提交,如果不提交,将来这个窗口一关,这个SQL其实不会被修改生效的。
在MySQL中,开启事务后面的其实也是要自己手动提交
drop table if exists account;
-- 创建帐户表
create table account (
id int primary key auto_increment,
name varchar(10),
money double(10,2)
);
-- 添加数据
insert into account(name,money) values('张三',1000),('李四',1000);
select * from account;
select * from account;
update account set money = 1000;
-- 转账操作
-- 开启事务
begin; -- 开启这个事务后,数据会临时更改,在当前这个用户会更改,在anotheraccount用户中查询不会更改
-- start transaction;
-- 1.查询李四的余额
-- select money from account where name = '李四';
-- 2.把李四的帐户 -500
update account set money = money - 500 where name = '李四';
-- 模拟异常
-- 出错了...
-- 3.把张三的帐户 +500
update account set money = money + 500 where name = '张三'
-- select money from account where name = '张三';
-- 提交事务
commit;
-- 回滚事务
rollback; -- 执行一下,回滚事务就相当于回滚到开启事务之前的这个状态
select * from account;
-- 1.查询事务的默认提交方式
select @@autocommit;
-- 1 自动提交 0 手动提交
-- 修改事务的提交方式,改为手动提交
set @@autocommit = 0;
set @@autocommit = 1;
-- 2.把李四的帐户 -500
update account set money = money - 500 where name = '李四';
-- 1 默认为事务自动提交,也就是做了一个操作之后,在其他窗口查也是一样的结果,就相当于操作后面写了一个 commit
-- 0 默认为事务手动提交,了就是做了一个操作之后,其实做了一个临时的更改,在这个窗口临时改了,在其它窗口没有更改,因为没有commit提交事务
-- commit
commit;
select * from account;
update account set money = 2000 where id = 1;