范式&多表查询

范式

什么是范式
范式是指:设计数据库表的规则(Normal Form) 好的数据库设计对数据的存储性能和后期的程序开发,都会产生重 要的影响。

范式的基本分类
目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式 (BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。
满足最低要求的范式是第一范式(1NF)。在 第一范式的基础上进一步满足更多规范要求的称为第二范式(2NF),其余范式以次类推。一般说来,数据库只需 满足第三范式(3NF)就行了

第一范式

1.数据库表的每一列都是不可分割的原子数据项,而不能是集合、数组、记录等非原子数据项。
2.实体中的某个属 性有多个值时,必须拆分为不同的属性。在符合第一范式(1NF)表中每个列的值只能是表的一个属性或一个属性 的一部分。
简而言之,第一范式每一列不可再拆分,称为原子性。

总结:
如果不遵守第一范式,查询出数据还需要进一步处理(查询不方便)。遵守第一范式,需要什么字段 的数据就查询什么数据(方便查询)。

第二范式

1.要求数据库表中的每个实例或记录必须可以被唯一地区分。
2.选取一个能区分每个实体的属性或属 性组,作为实体的唯一标识。
例如在员工表中的身份证号码即可实现每个员工的区分,该身份证号码即为候选键, 任何一个候选键都可以被选作主键。
在找不到候选键时,可额外增加属性以实现区分。

要求实体的属性完全依赖于主关键字。
所谓完全依赖是指不能存在仅依赖主关键字一部分的属性。
如果存在,那么这个属 性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。
为实现区分通常 需要为表加上一个列,以存储各个实例的唯一标识。
简而言之,第二范式就是在第一范式的基础上属性完全依赖于 主键。

第二范式特点:

  1. 一张表只描述一件事情
  2. 表中的每一个字段都依赖于主键
    总结:
    如果不准守第二范式,数据冗余,相同数据无法区分。遵守第二范式减少数据冗余,通过主键区分相 同数据。

第三范式
在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)
第三范式(3NF)是第二范式 (2NF)的一个子集,即满足第三范式(3NF)必须满足第二范式(2NF)。
简而言之,第三范式(3NF)要求一 个关系中不包含已在其它关系已包含的非主关键字信息。

第三范式:从表的外键必须使用主表的主键
总结:
如果不准守第三范式,可能会有相同数据无法区分,修改数据的时候多张表都需要修改(不方便修 改)。

遵守第三范式通过id可以区分相同数据,修改数据的时候只需要修改一张表(方便修改)。

多表查询

1.交叉连接查询(了解)

结果是两个表的乘积,并非我们所需
select * from a, b;

笛卡尔积现象
什么是笛卡尔积现象
select * from 表1 , 表2;
多表查询时左表的每条数据和右表的每条数据组合,这种效果成为笛卡尔积

如何清除笛卡尔积现象的影响
我们发现不是所有的数据组合都是有用的,只有员工表.dept_id = 部门表.id 的数据才是有用的。
所以需要通过条件 过滤掉没用的数据。
SELECT * FROM product, category WHERE product.category_id = category.cid;

2.内连接

用左边表的记录去匹配右边表的记录,如果符合条件的则显示
–> 显示结果: 两表关联的数据

建议: 为防止可能有些表内列名字相同,建议where条件后的类名使用表名.列名的形式
表名过长的话,建议使用别名(AS…)
一旦取别名,必须使用别名,否则报错

隐式内连接:

看不到 JOIN 关键字 (使用关键字inner join — inner可以省略)
select * from A,B where 条件;
条件 –> 从表的外键 = 主表的主键;
select * from A as a , B as b where a.() = b.()

显示内连接

使用 INNER JOIN … ON 语句 可以省略 INNER
SELECT 字段名 FROM 左表 INNER JOIN 右表 ON 条 件;
select * from A inner join B on 条件;

区别:
隐式内连接: 在查询结果的基础上去做的where条件过滤
显示内连接: 带着条件去查询结果,效率高.

应用场景:
查询唐僧的信息,显示员工id,姓名,性别,工资和所在的部门名称,我们发现需要联合2张表同时才能查询 出需要的数据,我们使用内连接

总结内连接查询步骤:
1. 确定查询哪些表
2. 确定表连接条件
3. 确定查询字段

3.外链接

左外连接

使用 LEFT OUTER JOIN … ON , OUTER 可以省略
SELECT 字段名 FROM 左表 LEFT OUTER JOIN 右表 ON 条件;
说明:
用左边表的记录去匹配右边表的记录,如果符合条件的则显示;
否则,显示NULL
查询结果为:左表的所有数据和右表中的关联的数据

右外连接

使用 RIGHT OUTER JOIN … ON , OUTER 可以省略
SELECT 字段名 FROM 左表 RIGHT OUTER JOIN 右表 ON 条件;
说明:
用右边表的记录去匹配左边表的记录,如果符合条件的则显示;
否则,显示NULL
可以理解为:右表的所有数据和左表中的关联的数据

子查询

一条SELECT语句结果作为另一条SELECT语法一部分(作为查询条件或查询结果或表)
SELECT 查询字段 FROM 表 WHERE 查询条件;
SELECT * FROM employee WHERE salary=(SELECT MAX(salary) FROM employee);

子查询需要放在()中
子查询结果的三种情况:
1. 子查询的结果是一个值的时候
2. 子查询结果是单列多行的时候
3. 子查询的结果是多行多列的时候

说明: 子查询结果只要是 单列 ,肯定在 WHERE 后面作为 条件 子查询结果只要是 多列 ,肯定在 FROM 后面 作为 表

子查询的结果是一个值
子查询结果只要是 单列 ,肯定在 WHERE 后面作为 条件
SELECT 查询字段 FROM 表 WHERE 字段=(子查询);
SELECT * FROM product WHERE category_id = (SELECT cid FROM category WHERE cname = ‘化妆品’);

子查询结果是单例多行
子查询结果是单例多行,结果集类似于一个数组,父查询 使用 IN 运算符
SELECT 查询字段 FROM 表 WHERE 字段 IN (子查询);

子查询的结果是多行多列
子查询结果只要是 多列 ,肯定在 FROM 后面作为 表
SELECT 查询字段 FROM (子查询) 表别名 WHERE
条件; 子查 询作为表需要取别名,否则这张表没用名称无法访问表中的字段

多表查询总结

子查询结果只要是 单列 ,肯定在 WHERE 后面作为 条件
SELECT 查询字段 FROM 表 WHERE 字段=(子查询);
子查询结果只要是 多列 ,肯定在 FROM 后面作为 表
SELECT 查询字段 FROM (子查询) 表别名 WHERE 条件;

多表查询规律总结

  1. 不管我们查询几张表,表连接查询会产出笛卡尔积,我们需要消除笛卡尔积,拿到正确的数据。我们需要找 到表与表之间通过哪个字段关联起来的(通常是 外键=主键 )
  2. 消除笛卡尔积规律:2张表需要1个条件,3张表需要2个条件,4张表需要3个条件。(条件数量=表的数 量-1),每张表都要参与进来
  3. 多表连接查询步骤:
    3.1. 确定要查询哪些表
    3.2. 确定表连接条件
    3.3. 确定查询字段
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值