多表的高级查询和事务安全
1.1笛卡尔积
### 功能
两张表的所有的字段进行了组合,这种现象称为笛卡尔积(又称为交叉连接)
### 语法
select * from 左表,右表
当要查询的表来自两张或者两张以上的表的时候就会出现笛卡尔积现象
解决笛卡尔积的现象有两种办法,
使用内连接和外连接,在两张表连接的时候进行限制符合连接条件的进行筛选
1.2 内连接
### 功能
那左表去匹配右边,符合连接条件的就留下,(是两个表的交集)
内连接不考虑连接的左右顺序
* 语法:
1. 显示内连接[推荐]
select ... from 左表 [inner] join 右表 on 条件过滤
2.隐式内连接
select ... from 左表 [inner] join 右表 where 条件过滤
1.3 外连接
* 功能:
外连接是连接两个表,展示左边的全部记录,那左表去匹配右边,若匹配的上就显示数据,如没有匹配的上就显示为null
分为左外联和右外联,两种功能一样,只是语法上有些不同
* 语法:
1.左外联[推荐]
select ... from 左表 left [outer] join 右表 on 过滤条件
这个是以左表为主表, 左边的数据全部显示,包过左表的null值,来匹配右表,如果符合过滤条件就显示
2.右外联
select ... form 左表 right [outer] join 右表 on 过滤条件
这个是以右表为主表显示右边的全部数据, 如果左边的数据符合过滤条件就显示
1.4 子查询
* 功能
一条select的查询语句的执行结果,作为另一条select查询语句的执行条件
使用的时候需要添加括号
* 语法:
1. 单值
select max(salary) from emp;
2. 单列多值
select name from emp;
3. 多列多值
select * from emp;
### 总结:
子查询结果为单列,作为条件使用在where之后使用
select ... from 表名 where 字段=查询的单个值的结果
select ... from 表名 where 字段 in (子查询);
子查询的结果作为多列多行的时候可以作为虚拟表放在from之后使用
select ... from (子查询) as 别名 ...
小结
1. 多表查询会出现笛卡尔积的现象
2. 消除笛卡尔积: 两个表1个条件,三张表两个条件
总结: n张表的话 判断条件的个数=表数-1;
3. 步骤
3.1 先确定有几张表
3.2 确定连接条件
3.3 确定显示字段
3.3 确地业务条件
事务安全TCL
3.1概述
如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败;
3.1.1手动开启事务
* 1.开始事务
start transaction;
2. 提交事务
commit;
3.回滚事务
rollback;
3.2自动开启事务
* mysql数据库默认情况下一条DML语句就是一个独立的事务
* 查看MYSQL是否开启自动提交
show variables like 'autocommit';
* 临时关闭事务的自动提交
set autocommit=OFF;
3.3事务原理
注意:代码保存之后必须执行rollback
,如果没有执行rollback处理,会影响同一个事务的中下一次提交数据;
3.4回滚点
* 功能:
当事务开启后,一部分的sql语句执行成功,添加一个回滚点,后续操作报废了,直接回到回滚点,保证之前的操作可以成功的提交
* 语法:
1.添加保存点
savapoint 保存点名称;
2. 回滚到保存点
rollback to 保存点名称;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sTe7R5ve-1595148467485)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1575942281628.png)]
3.5事务特性
* 1.原子性 A atomicity
如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败
2. 一致性 C consistency
数据在事务的执行前后,保证它的完整一致
3. 隔离性 I isolaation
多个事务之间相互独立,互不影响
4. 持久性 D durability
事务一旦提交,同步到数据库磁盘文件,不可逆
3.6 事务的隔离性
* 功能:
多个事务之间隔离的,相互独立的,但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可可以解决这些问题
1. 脏读:
一个事务中,读取到另一个事务未提交的数据
2. 不可重复读:
一个事务中,二次读取的内容不一致(update)
3. 幻读:
一个事务中,二次读取的数量不一致(insert、delete)
MySQL数据库隔离级别
级别 | 名字 | 隔离级别 | 脏读 | 不可重复读 | 幻读 | 数据库默认隔离级别 |
---|---|---|---|---|---|---|
1 | 读未提交 | read uncommitted | 是 | 是 | 是 | |
2 | 读已提交 | read committed | 否 | 是 | 是 | Oracle和SQL Server |
3 | 可重复读 | repeatable read | 否 | 否 | 是 | MySQL |
4 | 串行化 | serializable | 否 | 否 | 否 |
数据库性能:1>2>3>4
数据库安全:4>3>2>1
综合考量:2、3
演示不同隔离级别产生的问题
开启二个事务:A窗口 B窗口
1. 查看当前数据库隔离级别
show variables like '%isolation%';
2. 临时修改隔离级别
set session transaction isolation level 级别字符串;
update account set money=900 where id = 1;
3. 演示
3.1 脏读 设置隔离级别为 read uncommitted;
set session transaction isolation level read uncommitted;
3.2 解决脏读 设置隔离级别为 read committed;
set session transaction isolation level read committed;
3.3 解决不可重复读 设置隔离级别为 repeatable read;
set session transaction isolation level repeatable read;
4.3 串行化 设置隔离级别 serializable;
set session transaction isolation level serializable;
脏读:一个事务读到另一个事务未提交的数据
不可重复读: 一个事务中两次读取到的数据不一致
可重复读:一个事物中两次读取到的数据一致
最后一个隔离级别: serializable