1,约束
![](https://i-blog.csdnimg.cn/blog_migrate/90c9d632c46f2c4d3f1e766698e203ba.png)
![](https://i-blog.csdnimg.cn/blog_migrate/0a3de4b25d49fb7da12b5fbcdcc0300d.png)
1.1 概念
![](https://i-blog.csdnimg.cn/blog_migrate/f0962ada2ade9ac038065641b3362d54.png)
1.2 分类
![](https://i-blog.csdnimg.cn/blog_migrate/75f8e1a3a3601f1b432ccf5967d2b0aa.png)
![](https://i-blog.csdnimg.cn/blog_migrate/dafa574afc80096f8bcf0a9417d25077.png)
外键约束
概述
![](https://i-blog.csdnimg.cn/blog_migrate/b282e4b6f7a1e367335ea3b7b62d6782.png)
语法
![](https://i-blog.csdnimg.cn/blog_migrate/1ca377d82984440c4ef4635639ca298e.png)
* 添加外键约束
```sql
-- 创建表时添加外键约束
CREATE TABLE 表名(
列名 数据类型,
…
[CONSTRAINT] [外键名称] FOREIGN KEY(外键列名) REFERENCES 主表(主表列名)
);
```
```sql
-- 建完表后添加外键约束
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主表列名称);
```
* 删除外键约束
```sql
ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;
```
1.8.3 练习
![](https://i-blog.csdnimg.cn/blog_migrate/38c048b7a778b1e012666d82fa0900cc.png)
-- 删除表
DROP TABLE IF EXISTS emp;
DROP TABLE IF EXISTS dept;
-- 部门表
CREATE TABLE dept(
id 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(id)
);
![](https://i-blog.csdnimg.cn/blog_migrate/8680cc30540bfeec75ec3f31e190cdb3.png)
-- 添加 2 个部门
insert into dept(dep_name,addr) values
('研发部','广州'),('销售部', '深圳');
-- 添加员工,dep_id 表示员工所在的部门
INSERT INTO emp (NAME, age, dep_id) VALUES
('张三', 20, 1),
('李四', 20, 1),
('王五', 20, 1),
('赵六', 20, 2),
('孙七', 22, 2),
('周八', 18, 2);
![](https://i-blog.csdnimg.cn/blog_migrate/662d3b2fcd01102de863711ab2bc3677.png)
删除外键
```sql
alter table emp drop FOREIGN key fk_emp_dept;
```
重新添加外键
```sql
alter table emp add CONSTRAINT fk_emp_dept FOREIGN key(dep_id) REFERENCES dept(id);
2,数据库设计
2.1 数据库设计简介
![](https://i-blog.csdnimg.cn/blog_migrate/399c37dc97e0bbcbcddc938f5b766241.png)
![](https://i-blog.csdnimg.cn/blog_migrate/bf8838a96e4ba02e719c0ca1bb112701.png)
![](https://i-blog.csdnimg.cn/blog_migrate/cd0f7049cc5655aa377cb528dabe4b28.png)
![](https://i-blog.csdnimg.cn/blog_migrate/3e8b159fb72410cd242a098f5f5e3ab1.png)
2.2 表关系(一对多)
![](https://i-blog.csdnimg.cn/blog_migrate/bad9eb64980738e50aff2fef390d01e1.png)
2.3 表关系(多对多)
![](https://i-blog.csdnimg.cn/blog_migrate/b3fe90c18f79dbbfc61f5ed253437d30.png)
![](https://i-blog.csdnimg.cn/blog_migrate/36fb48d3301904ead50e5858644016af.png)
![](https://i-blog.csdnimg.cn/blog_migrate/798f36b859a3fcc32e0943cb84801aff.png)
-- 删除表
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);
```
![](https://i-blog.csdnimg.cn/blog_migrate/1595e81be28614a15e7e469682ef64db.png)
2.4 表关系(一对一)
![](https://i-blog.csdnimg.cn/blog_migrate/965a290bd2cee9067c669fc42bae90d6.png)
![](https://i-blog.csdnimg.cn/blog_migrate/2959cd4fddf0ffc280ca03c9dcbee58f.png)
create table tb_user_desc (
id int primary key auto_increment,
city varchar(20),
edu varchar(10),
income int,
status char(2),
des varchar(100)
);
create table tb_user (
id int primary key auto_increment,
photo varchar(100),
nickname varchar(50),
age int,
gender char(1),
desc_id int unique,
-- 添加外键
CONSTRAINT fk_user_desc FOREIGN KEY(desc_id) REFERENCES tb_user_desc(id)
);
![](https://i-blog.csdnimg.cn/blog_migrate/8e7a799de7abb30c52b09236cb9a169f.png)
2.5 数据库设计案例
根据下图设计表及表和表之间的关系:
经过分析,我们分为 专辑表 曲目表 短评表 用户表 4张表。
![](https://i-blog.csdnimg.cn/blog_migrate/2ef03980711656f1760c81cdcf86c693.png)
3,多表查询
![](https://i-blog.csdnimg.cn/blog_migrate/1bd6a7725295ca77166ba36d155e7b37.png)
DROP TABLE IF EXISTS emp;
DROP TABLE IF EXISTS dept;
# 创建部门表
CREATE TABLE dept(
did INT PRIMARY KEY AUTO_INCREMENT,
dname VARCHAR(20)
);
# 创建员工表
CREATE TABLE emp (
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(10),
gender CHAR(1), -- 性别
salary DOUBLE, -- 工资
join_date DATE, -- 入职日期
dep_id INT,
FOREIGN KEY (dep_id) REFERENCES dept(did) -- 外键,关联部门表(部门表的主键)
);
-- 添加部门数据
INSERT INTO dept (dNAME) VALUES ('研发部'),('市场部'),('财务部'),('销售部');
-- 添加员工数据
INSERT INTO emp(NAME,gender,salary,join_date,dep_id) VALUES
('孙悟空','男',7200,'2013-02-24',1),
('猪八戒','男',3600,'2010-12-02',2),
('唐僧','男',9000,'2008-08-08',2),
('白骨精','女',5000,'2015-10-07',3),
('蜘蛛精','女',4500,'2011-03-14',1),
('小白龙','男',2500,'2011-02-14',null);
![](https://i-blog.csdnimg.cn/blog_migrate/ac2d7472c1e0adbf2c4f3fa67d40bc09.png)
select * from emp , dept; -- 从emp和dept表中查询所有的字段数据
![](https://i-blog.csdnimg.cn/blog_migrate/3bed6f0b4b610150dc8fd4f7ddbe9941.png)
select * from emp , dept where emp.dep_id = dept.did;
![](https://i-blog.csdnimg.cn/blog_migrate/84362a5ac04138f9c29c654a7ecabac8.png)
![](https://i-blog.csdnimg.cn/blog_migrate/4ed1055dcf9a3abdc99196bb22e0aba0.png)
左连接:A 和A∩B这块;
右连接:B 和A∩B这块;
内连接查询
语法
![](https://i-blog.csdnimg.cn/blog_migrate/0c20b93e269d63d41a99fad161c8a507.png)
案例
隐式内连接
![](https://i-blog.csdnimg.cn/blog_migrate/b294132c054c5ff486986ecf45b3e8cb.png)
SELECT
*
FROM
emp,
dept
WHERE
emp.dep_id = dept.did;
![](https://i-blog.csdnimg.cn/blog_migrate/b61f71d8f094657d3850609bee3ee50c.png)
![](https://i-blog.csdnimg.cn/blog_migrate/ca5055e4d809e850abdc615314432152.png)
SELECT
emp. NAME,
emp.gender,
dept.dname
FROM
emp,
dept
WHERE
emp.dep_id = dept.did;
上面语句中使用表名指定字段所属有点麻烦,
sql
也支持给表指别名,上述语句可以改进为
SELECT
t1. NAME,
t1.gender,
t2.dname
FROM
emp t1,
dept t2
WHERE
t1.dep_id = t2.did;、
显式内连接
![](https://i-blog.csdnimg.cn/blog_migrate/45014c2e215a7c7ce8c5649b6dada519.png)
select * from emp inner join dept on emp.dep_id = dept.did;
-- 上面语句中的inner可以省略,可以书写为如下语句
select * from emp join dept on emp.dep_id = dept.did;
![](https://i-blog.csdnimg.cn/blog_migrate/5b8c11917d96a1f5be5fac465e67f74f.png)
3.2 外连接查询
案例
![](https://i-blog.csdnimg.cn/blog_migrate/7a27aefd1d78634c1fb8bb2880af3fac.png)
select * from emp left join dept on emp.dep_id = dept.did;
![](https://i-blog.csdnimg.cn/blog_migrate/f79cec5017072b962569ae470f23f0de.png)
查询dept表所有数据和对应的员工信息(右外连接)
SELECT * FROM emp RIGHT JOIN dept on emp.dep_id = dept.did;
![](https://i-blog.csdnimg.cn/blog_migrate/84d9cbc108409b6ea22df67568d4257b.png)
结果显示查询到了右表(
dept
)中所有的数据及两张表能关联的数据。
要查询出部门表中所有的数据,
也可以通过左外连接实现,只需要将两个表的位置进行互换
:
select * from dept left join emp on emp.dep_id = dept.did;
3.3 子查询
概念
查询中嵌套查询,称嵌套查询为子查询。
什么是查询中嵌套查询呢?我们通过一个例子来看:
需求:查询工资高于猪八戒的员工信息。
来实现这个需求,我们就可以通过二步实现,
第一步:先查询出来 猪八戒的工资
select salary from emp where name = '猪八戒'
![](https://i-blog.csdnimg.cn/blog_migrate/c254f9c450051084d4f2c87203d48171.png)
第二步:查询工资高于猪八戒的员工信息
select
*
from
emp
where
salary
>
3600
;
![](https://i-blog.csdnimg.cn/blog_migrate/6e9383497e180218289a79108337be40.png)
第三步中的
3600
可以通过第一步的
sql
查询出来,所以将
3600
用第一步的
sql
语句进行替换
select * from emp where salary > (select salary from emp where name = '猪八戒');
![](https://i-blog.csdnimg.cn/blog_migrate/0b0d04757cc996e9c525e1f2e457c859.png)
这就是查询语句中嵌套查询语句。
子查询根据查询结果不同,作用不同
子查询语句结果是单行单列,子查询语句作为条件值,使用
= != > <
等进行条件判断
子查询语句结果是多行单列,子查询语句作为条件值,使用
in
等关键字进行条件判断
子查询语句结果是多行多列,子查询语句作为虚拟表
案例
查询
'
财务部
'
和
'
市场部
'
所有的员工信息
-- 查询 '财务部' 或者 '市场部' 所有的员工的部门did
select did from dept where dname = '财务部' or dname = '市场部';
![](https://i-blog.csdnimg.cn/blog_migrate/85aa83a220459d9d8715b8b8d16e207c.png)
select * from emp where dep_id in (select did from dept where dname = '财务部' or dname = '市场部');
![](https://i-blog.csdnimg.cn/blog_migrate/e8817bd6a8b1eaa4a0cf8359570d759c.png)
案例二
查询入职日期是
'2011-11-11'
之后的员工信息和部门信息
-- (第一步) 查询入职日期是 '2011-11-11' 之后的员工信息
select * from emp where join_date > '2011-11-11' ;
-- (第二步)将上面语句的结果作为虚拟表和dept表进行内连接查询
SELECT * FROM(select * from emp where join_date > '2011-11-11') t1,dept where t1.dep_id = dept.did;
![](https://i-blog.csdnimg.cn/blog_migrate/0e7cbebe410dc0029f82a166bd7d9249.png)
3.4 案例
环境准备:
DROP TABLE IF EXISTS
emp;
DROP TABLE IF EXISTS
dept;
DROP TABLE IF EXISTS
job;
DROP TABLE IF EXISTS
salarygrade;
--
部门表
CREATE TABLE
dept
(
did
INT
PRIMARY KEY PRIMARY KEY
,
--
部门
id
dname
VARCHAR
(
50
)
,
--
部门名称
loc
VARCHAR
(
50
)
--
部门所在地
)
;
--
职务表,职务名称,职务描述
CREATE TABLE
job
(
id
INT
PRIMARY KEY
,
jname
VARCHAR
(
20
)
,
description
VARCHAR
(
50
)
)
;
--
员工表
CREATE TABLE
emp
(
id
INT
PRIMARY KEY
,
--
员工
id
ename
VARCHAR
(
50
)
,
--
员工姓名
job_id
INT
,
--
职务
id
mgr
INT
,
--
上级领导
joindate
DATE
,
--
入职日期
salary
DECIMAL
(
7
,
2
)
,
--
工资
bonus
DECIMAL
(
7
,
2
)
,
--
奖金
dept_id
INT
,
--
所在部门编号
CONSTRAINT
emp_jobid_ref_job_id_fk
FOREIGN KEY
(
job_id
)
REFERENCES
job
(
id
)
,
CONSTRAINT
emp_deptid_ref_dept_id_fk
FOREIGN KEY
(
dept_id
)
REFERENCES
dept
(
did
)
)
;
--
工资等级表
CREATE TABLE
salarygrade
(
grade
INT
PRIMARY KEY
,
--
级别
losalary
INT
,
--
最低工资
hisalary
INT
--
最高工资
)
;
--
添加
4
个部门
INSERT INTO
dept
(
did,dname,loc
)
VALUES
(
10
,
'
教研部
'
,
'
北京
'
)
,
(
20
,
'
学工部
'
,
'
上海
'
)
,
(
30
,
'
销售部
'
,
'
广州
'
)
,
(
40
,
'
财务部
'
,
'
深圳
'
)
;
--
添加
4
个职务
INSERT INTO
job
(
id, jname, description
)
VALUES
(
1
,
'
董事长
'
,
'
管理整个公司,接单
'
)
,
(
2
,
'
经理
'
,
'
管理部门员工
'
)
,
(
3
,
'
销售员
'
,
'
向客人推销产品
'
)
,
(
4
,
'
文员
'
,
'
使用办公软件
'
)
;
--
添加员工
INSERT INTO
emp
(
id,ename,job_id,mgr,joindate,salary,bonus,dept_id
)
VALUES
(
1001
,
'
孙悟空
'
,
4
,
1004
,
'2000-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'
,
'28500.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
)
;
需求
1. 查询所有员工信息。查询员工编号,员工姓名,工资,职务名称,职务描述
/*
分析:
1.
员工编号,员工姓名,工资 信息在
emp
员工表中
2.
职务名称,职务描述 信息在
job
职务表中
3. job
职务表 和
emp
员工表 是 一对多的关系
emp.job_id = job.id
*/
--
方式一 :隐式内连接
SELECT
emp
.id
,
emp
.ename
,
emp
.salary
,
job
.jname
,
job
.description
FROM
emp,
job
WHERE
emp
.job_id
=
job
.id
;
--
方式二 :显式内连接
SELECT
emp
.id
,
emp
.ename
,
emp
.salary
,
job
.jname
,
job
.description
FROM
emp
INNER JOIN
job
ON
emp
.job_id
=
job
.id
;
2.
查询员工编号,员工姓名,工资,职务名称,职务描述,部门名称,部门位置
/*
分析:
1.
员工编号,员工姓名,工资 信息在
emp
员工表中
2.
职务名称,职务描述 信息在
job
职务表中
3. job
职务表 和
emp
员工表 是 一对多的关系
emp.job_id = job.id
4.
部门名称,部门位置 来自于 部门表
dept
5. dept
和
emp
一对多关系
dept.id = emp.dept_id
*/
--
方式一 :隐式内连接
SELECT
emp
.id
,
emp
.ename
,
emp
.salary
,
job
.jname
,
job
.description
,
dept
.dname
,
dept
.loc
FROM
emp,
job,
dept
WHERE
emp
.job_id
=
job
.id
and
dept
.id
=
emp
.dept_id
;
--
方式二 :显式内连接
SELECT
emp
.id
,
emp
.ename
,
emp
.salary
,
job
.jname
,
job
.description
,
dept
.dname
,
dept
.loc
FROM
emp
INNER JOIN
job
ON
emp
.job_id
=
job
.id
INNER JOIN
dept
ON
dept
.id
=
emp
.dept_id
3.
查询员工姓名,工资,工资等级
/*
分析:
1.
员工姓名,工资 信息在
emp
员工表中
2.
工资等级 信息在
salarygrade
工资等级表中
3. emp.salary >= salarygrade.losalary and emp.salary <= salarygrade.hisalary
*/
完整版
SELECT
emp.ename,
emp.salary,
salarygrade.grade,
salarygrade.losalary,
salarygrade.hisalary
FROM emp,salarygrade
WHERE emp.salary >= salarygrade.losalary and emp.salary <= salarygrade.hisalary
简略版(改名)
SELECT
emp
.ename
,
emp
.salary
,
t2.
*
FROM
emp,
salarygrade t2
WHERE
emp
.salary
>=
t2
.losalary
AND
emp
.salary
<=
t2
.hisalary
4.
查询员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级 (跳过)
/*
分析:
1.
员工编号,员工姓名,工资 信息在
emp
员工表中
2.
职务名称,职务描述 信息在
job
职务表中
3. job
职务表 和
emp
员工表 是 一对多的关系
emp.job_id = job.id
4.
部门名称,部门位置 来自于 部门表
dept
5. dept
和
emp
一对多关系
dept.id = emp.dept_id
6.
工资等级 信息在
salarygrade
工资等级表中
7. emp.salary >= salarygrade.losalary and emp.salary <= salarygrade.hisalary
*/
SELECT
emp
.id
,
emp
.ename
,
emp
.salary
,
job
.jname
,
job
.description
,
dept
.dname
,
dept
.loc
,
t2
.grade
FROM
emp
INNER JOIN
job
ON
emp
.job_id
=
job
.id
INNER JOIN
dept
ON
dept
.did
=
emp
.dept_id
INNER JOIN
salarygrade t2
ON
emp
.salary
BETWEEN
t2
.losalary
and
t2
.hisalary
;
5.
查询出部门编号、部门名称、部门位置、部门人数 (跳过)
/*
分析:
1.
部门编号、部门名称、部门位置 来自于部门
dept
表
2.
部门人数
:
在
emp
表中 按照
dept_id
进行分组,然后
count(*)
统计数量
3.
使用子查询,让部门表和分组后的表进行内连接
*/
--
根据部门
id
分组查询每一个部门
id
和员工数
select
dept_id,
count
(
*
)
from
emp
group by
dept_id;
SELECT
dept
.id
,
dept
.dname
,
dept
.loc
,
t1
.count
FROM
dept,
(
SELECT
dept_id,
count
(
*
)
count
FROM
emp
GROUP BY
dept_id
)
t1
WHERE
dept
.id
=
t1
.dept_id
4,事务
4.1 概述
![](https://i-blog.csdnimg.cn/blog_migrate/d38e3000db1a3f98f3a3849a7ac95e20.png)
![](https://i-blog.csdnimg.cn/blog_migrate/dc886e679256ccb4ba1d9f96a718f529.png)
![](https://i-blog.csdnimg.cn/blog_migrate/2a5a39fd64d5a134496c51e30352d299.png)
4.2 语法
![](https://i-blog.csdnimg.cn/blog_migrate/69b9e64de9e9189a082d98d0293b17e4.png)
4.3 代码验证
环境准备
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
)
;
不加事务演示问题
--
转账操作
-- 1.
查询李四账户金额是否大于
500
-- 2.
李四账户
-500
UPDATE
account
set
money
=
money
-
500
where
name
=
'
李四
'
;
出现异常了
...
--
此处不是注释,在整体执行时会出问题,后面的
sql
则不执行
-- 3.
张三账户
+500
UPDATE
account
set
money
=
money
+
500
where
name
=
'
张三
'
;
在新的查询表里查找还是一样的结果。
添加事务
sql
如下:
--
开启事务
BEGIN
;
--
转账操作
-- 1.
查询李四账户金额是否大于
500
-- 2.
李四账户
-500
UPDATE
account
set
money
=
money
-
500
where
name
=
'
李四
'
;
出现异常了
...
--
此处不是注释,在整体执行时会出问题,后面的
sql
则不执行
-- 3.
张三账户
+500
UPDATE
account
set
money
=
money
+
500
where
name
=
'
张三
'
;
--
提交事务
COMMIT
;
--
回滚事务
ROLLBACK
;
(添加了begin出现异常,只在
当前查询表出错,新的查询表查询还是2000元)
回滚类似撤回
上面
sql
中的执行成功进选择执行提交事务,而出现问题则执行回滚事务的语句。以后我们肯定不可能这样操作,而是在java
中进行操作,在
java
中可以抓取异常,没出现异常提交事务,出现异常回滚事务。
4.4 事务的四大特征
面试题常问四大特征(ACIE)
原子性(
A
tomicity
)
:
事务是不可分割的最小操作单位,要么同时成功,要么同时失败
一致性(
C
onsistency
)
:
事务完成时,必须使所有的数据都保持一致状态
隔离性(
I
solation
)
:
多个事务之间,操作的可见性
持久性(
D
urability
)
:
事务一旦提交或回滚,它对数据库中的数据的改变就是永久的
说明:
mysql
中事务是自动提交的。
也就是说我们不添加事务执行
sql
语句,语句执行完毕会自动的提交事务。
可以通过下面语句查询默认提交方式:
SELECT
@@autocommit
;
查询到的结果是
1
则表示自动提交,结果是
0
表示手动提交。当然也可以通过下面语句修改提交方式
set
@@autocommit
=
0
;
Oracle数据库是需要手动提交事务;