(新手友好)MySQL学习笔记(12):触发器,视图,三范式

触发器

trigger,在表的插入(insert),更新(update),删除(delete)操作发生时自动执行MySQL语句

创建触发器时需要给出的信息:

  • 触发器名
  • 在操作前还是操作后触发(before/after)
  • 被什么操作触发(insert/update/delete)
  • 关联的表

使用触发操作的数据:

  • insert:可通过new访问被插入的行,before insert 可以更新new中的值(允许更改被插入的值)。
  • update:old访问更新前的值,new访问更新后的值。
  • update:可通过old访问被删除的行,old中的值是只读的。
sql 复制代码
#创建触发器
create trigger 触发器名 
before|after  
update|insert|delete on 表名
for each row
begin
    触发器逻辑;
end;
 
 #删除触发器
 drop trigger [if exists] 触发器名;
sql 复制代码
#更新部门,对应部门的员工涨工资
drop trigger if exists mytrigger;
create trigger mytrigger after update on dept
for each row
begin
    update emp
        set sal = sal+100 
    where deptno = new.deptno;
end;

update dept
set loc = 'BEIJING'
where loc = 'DALLAS';

触发器练习

需求:给部门表添加员工数量字段,员工表添加员工时对应部门员工数量自动加1

  1. dept表添加一个字段:员工数量
  2. 部门表的员工数量更新为正确值
  3. 写一个触发器,当员工表添加员工时,对于部门员工数量加1
  4. 员工表添加员工测试

视图

view,由查询结果形成的一个虚拟的表。视图不能索引,也不能有关联的触发器。

sql 复制代码
create view 视图名 as 查询语句;
#修改视图
alter view 视图名 as 查询语句;
#删除视图
drop view [if exists] 视图名;
#查看创建视图语句
show create view 视图名;
sql 复制代码
#查询出员工的部门名称,员工的领导名和薪水等级
create view emp_all as
select e1.ename,e2.ename mgr_name,d.dname,s.grade
from emp e1
left join emp e2 on e1.mgr = e2.empno
join dept d on e1.deptno = d.deptno
join salgrade s on e1.sal between losal and hisal;

select * from emp_all;

视图的作用:

  • 重用SQL语句
  • 简化查询语句,隐藏复杂的SQL
  • 安全:使用视图的用户只能访问他们被允许查询的结果集

视图的实现原理:

  • 临时表算法:将视图的查询结果存放到临时表里,需要访问视图时,直接访问这个临时表,优点是可以处理复杂查询,缺点是引入了创建表的性能开销。
  • 合并算法:重写含有视图的查询,将视图的定义sql直接合并到查询sql里,性能更高。

MySQL优化器根据查询的具体情况来选择哪种算法。如果视图中包含group by,distinct,聚合函数等,只要无法在原表记录和视图记录中建立一一映射的场景中。MySQL都将使用临时表算法来实现视图。

不同视图与原表的联系:

  • 普通视图:通常不能直接更新,修改视图不会影响原表。
  • 可更新视图:可以直接更新,修改视图影响原表。
  • 物化视图:通常是只读的,修改视图不会影响原表。

注意:基于单表的视图,修改原表数据,可以通过维护视图完成视图的更新。

可更新视图:可以通过更新这个视图来更新视图涉及的相关表。只要指定了合适的条件,就可以更新,删除甚至是在相关表中插入数据。

sql 复制代码
#查看合并算法
create view abc as select * from emp;
explain select * from abc;
#查看临时表算法
create view dept_emp as select * from emp group by deptno;
explain select * from dept_emp;
#修改可更新视图
insert into abc(empno) values(111);
update abc 
set
    empno = 222
where empno = 111;
insert into dept_emp(empno) values(111);
#不可更新视图
create view abc2 as select deptno from emp;
insert into abc2(deptno) values(111);#无主键,导致更新时主键为空报错

create view abc2 as select empno from emp;
insert into abc2(empno) values(111);#不报错
insert into abc2(empno) values(111);#报错,已经有主键值为111的记录第二次添加主键值为111会报错

create view abc2 as select deptno * 2 from emp;
update abc2
set
    deptno = 222 
where deptno in NULL;#不存在deptno字段,因为abc中的是deptno*2字段,所以无法修改,报错

三范式

范式是关系型数据库设计的一种规范,目标是消除冗余,建立结构合理的数据库,从而提升数据存储和使用的性能。

第一范式(1NF)

每列的原子性,表中的每一个字段都是不可分割的,同一列中不能有多个值。第一范式是对关系模式的基本要求,不满足第一范式的数据库不是关系型数据库。

  • 不满足第一范式的示例:

|------|------|-------------------------|
| 学生编号 | 学生姓名 | 联系方式 |
| 1001 | 张三 | zs@163.com,135999999999 |
| 1002 | 李四 | ls@163.com,136889999999 |
| 1003 | 王五 | ww@163.com,125999999999 |

注意:第一范式要根据实际需求来定,联系方法中存在邮箱和电话,即不满足第一范式

第一范式怎么要求,举个例子,如果考虑地址字段(河南省郑州市高兴区知行街135号)是否符合第一范式,如果经常访问地址中的城市部分,这个字段就不符合第一范式,需要进行拆分,可以拆分成河南省,郑州市,高兴区知行街135号。如果经常访问整个地址,就符合第一范式,拆分反而不利于查询完整地址。

第二范式(2NF)

确保唯一性和依赖性,每个表都有主键,且其他字段完全依赖主键。

第二范式是在第一范式的基础上,要求表中的每一条数据可以被唯一区分,通常使用主键实现,其他所有字段都完全依赖主键。

其他字段依赖主键是指,其他每个字段都与主键完全相关,当确定主键的值时就能确定其他所有字段的值。也就是说一张表只能存一种数据,不可以吧多种数据存到一张表中,比如课程表的内容存到学生表中。

完全依赖是指,联合主键时,其他字段不可以只依赖主键中的某个字段,必须依赖联合主键中的每一个字段。

  • 不满足第二范式的示例:

成绩表(score)

|------|-----|------|----|
| 学号 | 课程号 | 学生姓名 | 成绩 |
| 1001 | 001 | 张三 | 90 |
| 1002 | 002 | 李四 | 80 |
| 1001 | 001 | 张三 | 90 |

其中学生名只依赖学号,与本表中的联合主键(学号,课程号)产生了部分依赖,即只依赖学号,所以该表不满足第二范式。

第三范式(3NF)

在第二范式的基础上,非主键字段必须直接依赖于主键,不能存在传递依赖。

  • 不满足第三范式的示例:

|-----|------|------|-------|
| 课程号 | 课程名 | 授课教师 | 教师办公室 |
| 001 | 线性代数 | 张三 | 302 |
| 002 | 概率论 | 李四 | 303 |
| 001 | 数理统计 | 王五 | 302 |

我们可以看到,整张表中不存在部分依赖,但是教师办公室依赖于授课教师,授课教师又依赖于课程号,形成了(课程号)->(授课教师)->(教师办公室)传递依赖,因此不满足第三范式。

范式总结

  • 1NF:原子性,字段分割到不可分割。
  • 2NF:唯一性和完全依赖,要有主键,且其他字段完全依赖于主键。
  • 3NF:没有传递依赖。

范式的优缺点:

  • 优点:
    • 重复数据很少甚至没有。
    • 冗余字段少,表更小,可以更好的放在内存里,执行操作时更快。
    • 进行更新操作更快。
    • 可以更少的使用group by 和 distinct。
  • 缺点:进行复杂一点的查询需要关联,并且可能使索引无效。
相关推荐
醇醛酸醚酮酯1 小时前
MySQL 的语言体系
数据库·mysql·oracle
zlbbme_1 小时前
Android Studio学习笔记:为应用添加文本和图片
笔记·学习
He.ZaoCha1 小时前
多表查询-4-外连接
数据库·sql·mysql
许白掰2 小时前
Linux入门篇学习——Linux 编写第一个自己的命令,make 工具和 makefile 文件
linux·运维·服务器·学习
ladymorgana4 小时前
【数据库】PostgreSQL 与 MySQL 全方位对比
数据库·mysql·postgresql
张璐月4 小时前
mysql 散记:innodb引擎和memory引擎对比 sql语句少用函数 事务与长事务
数据库·sql·mysql
baynk7 小时前
逆向入门(9)汇编篇-bound指令的学习
汇编·学习
茫忙然9 小时前
【WEB】Polar靶场 Day7 详细笔记
笔记
future141211 小时前
游戏开发日记
数据结构·学习·c#