Java EE day04学习总结
今天主要学习聚合函数&表约束
思维导图:
一.级联操作
1.概念:
当我们的一张表存在外键的时候,这个时候我们希望修改或者删除数据,如果删除了或者修改了主表数据,且从表会跟随着主表联动修改或者删除从表数据,这个时候就可以使用级联操作。
2.级联操作关键字:
级联删除:ON DELETE CASCADE
级联更新:ON UPDATE CASCADE
代码示例:
-- 创建员工表
CREATE TABLE emp(
id INT PRIMARY KEY auto_increment,
name VARCHAR(20),
dept_id INT,
-- 给外键字段添加级联更新(ON UPDATE CASCADE)、级联删除(ON DELETE CASCADE)
CONSTRAINT emp_dept_fk FOREIGN KEY(dept_id) REFERENCES dept(id) ON UPDATE CASCADE ON DELETE CASCADE
);
-- 修改主表主键ID,从表联动修改
UPDATE dept SET id = 3 WHERE id = 1;
-- 删除主表主键ID,从表联动删除
DELETE FROM dept WHERE id = 3;
二.数据库设计与规范
1.数据库层次两个阶段
(1)数据库的需求分析
<1>原始需求(我需要上传一个视频并且显示)
<2>我们需要将客户或者产品的原始需求转换为业务需求
<3>我需要上传一个视频并且显示的分析
图片字段
标题字段
价格字段
访问量字段
评价字段
....
(2)数据库的需求设计
<1>将整理好的需求转换为一个业务模型
class voide[String img,String title,doube price..]
<2>将后端或者其他代码转化为数据库参数
create table voide(img varchar(20),title varchar(20),price double(8,2)...)
2.多表之间的关系(重要)
在现实的生活当中,对象跟对象之间肯定是有一定练习的,比如学生和老师,员工和部门,司机与乘客。其实这也是就我们第一节课所说的关系型数据和非关系的区别。
那么我们这种关系型数据库就一定要设计好表和表之间的关系
3.一对多关系(多对一) [最常用]
一对多(1:n),比如一个老师对应多个学生
一个部门对应多个员工
一个账号对应多个订单
一对多的建表原则:在多的一方设定为从表(外键),在少的一方设定为主表(主键),然后从表的外键关联了主表的主键。
4.多对多关系 [一般]
多对多(m:n):
学生和课程
老师和学生
多对多的建表原则:这个关系比较特殊,所有需要实现多对多就一定要依靠一个中间表完成,且这个中间表必须最少具备两个字段,然后这两个字段分别指向了主表和从表
5.一对一关系 [几乎不用,因为一张表完全就可以实现一对一]
一对一(1:1),在实际的开发当中,基本不用,因为1:1的关系其实完全可以一张表完成
学号对姓名
公民对身份证
三.表设计的五大范式
1.什么是范式?
一个好的数据库设计多存储和性能以及后期从程序的开发维护起到了一个至关重要的作用,为了建立更加科学、更加合理的数据库流程,就有人设计了一套来优化数据库存储的规则,这个规则就被称之范式规则。
2.有哪一些范式?
目前关系型数据库一共存在了5-6种设计范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第五范式(5NF)【完美级范式】。
最低要求的第一范式,必须遵循 否则数据库无法跟程序代码接轨、一般实现第二或者第三范式就可以。
3.第一范式
(1)要求数据库的表字段每一个是不可分割的,必须是具备原子性,不能是数组或者集合类的非原子性,就是说表中的每一个列,里面数据一旦定义好,那么就不要去切割他(不要去拆分)
4.第二范式
(1)概念:第二范式的要求是必须满足第一范式,要求表中的每一个字段都强烈的依赖于主键,其实就是第二范式就是在第一范式的基础上,要所有的列必须依赖于主键。
(2)第二范式的特点:
<1>一张表只能表述一件事情
<2>表中的每一个字段都必须和主键有依赖关系
5.第三范式
第三范式的要求是必须先满足第二范式,表中的每一个字段列都直接依赖于主键,任何非主键列都不能进行任何形式的传递依赖。
什么是传递依赖,如果现在有三张表 A<--B<--C,
6.总结
范式名称 |
特点 |
1NF |
要求表的数据是不可拆分,具备原子性 |
2NF |
一张表只做一件事,表字段都跟主键有直接依赖关系 |
3NF |
不产生传递关系,表的每一个字段和主键必须是直接依赖,而不是间接依赖 |
四.多表查询
1.交叉连接查询
SELECT 表1.字段名,表2.字段名 FROM 表1,表2;
SELECT dept1.name,emp.name FROM dept1,emp;
2.交叉连接查询产生笛卡尔积
所谓的笛卡尔积,又被称之为笛卡尔乘积。
就是左边的数据 * 右边的数据 = 查询数据
3.解决笛卡尔积
笛卡尔积的主要问题还是有因为数据没有进行过滤,此时只需要将外键和主键进行匹配限制即可。
4.内连接查询
两张表交叉后的,且过滤后的数据查询称之为内连接查询
5.隐式内连接查询(解决笛卡尔积)
SELECT * FROM 主键表,外键表 WHERE 主键表.主键列 = 外键表.外键类;
SELECT dept1.name,emp.name FROM dept1,emp WHERE dept1.id = emp.dept_id;
-- 为了解决多表查询时候,表名过长的问题 我们可以是表别名缩减
SELECT d.name,e.name FROM dept1 d,emp e WHERE d.id = e.dept_id;
6.显式内连接
SELECT * FROM
emp
INNER JOIN
dept1
ON
emp.dept_id = dept1.id;
7.左外连接查询
当两张表进行查询的时候,可能出现数据量不一致的问题,那么这个时候就需要觉得以谁作为参考,而左外连接则以LEFT OUTER JOIN的左边数据表作为参考。
当左表和右表数据满足连接条件的时候,就显示所满足条件的数据,如果不满足 则显示null.
SELECT e.name,d.name FROM
emp e
LEFT OUTER JOIN
dept d
ON
e.dept_id = d.id;
8.右外连接查询
当两张表进行查询的时候,可能出现数据量不一致的问题,那么这个时候就需要觉得以谁作为参考,而左外连接则以RIGHT OUTER JOIN的右边数据表作为参考。
当左表和右表数据满足连接条件的时候,就显示所满足条件的数据,如果不满足 则显示null.
SELECT e.name,d.name FROM
emp e
RIGHT OUTER JOIN
dept d
ON
e.dept_id = d.id;
9.子查询
所谓的子查询就是将一个SQL语句查询出来的结果充当为一个单列数据,然后这个结果提供其他SQL语句操作
普通查询方式:查询员工最高的员工信息
- 先查询最高工资SELECT MAX(salary) FROM emp;
- 根据最高工资查询员工信息SELECT * FROM emp WHERE salary = 200000;
子查询完成
SELECT * FROM emp WHERE salary = (SELECT MAX(salary) FROM emp);
10.如果是双列子查询需要使用IN关键字进行处理
查询开发部和人事部是所有员工信息
SELECT id FROM dept1 WHERE name = '人事部';
SELECT * FROM emp WHERE dept_id = 3;
子查询完成
SELECT * FROM emp WHERE dept_id IN(SELECT id FROM dept1 WHERE name = '人事部' OR name = '研发部');
`