多表的设计_关联查询
数据库设计: 在数据库的设计中,常常会存在一些问题(字段里的内容都相同,也叫数据冗余),这样的问题可能会导致数据被破坏,为了解决数据的冗余,设计数据库时必需遵循一定的规则(5范式),平常遵循了3范式就足够了
编号 | 姓名 | 民族 | 年级 |
1 | 张三 | 汉 | 一年级 |
2 | 李四 | 汉 | 一年级 |
第一范式: 所有字段的值都是不可分解的,也就是保持原子性,这是最基本的范式
第二范式: 有主键,保证了记录的完整性
第三范式: 消除传递依赖,方便与理解,也就是消除冗余.比如:
订单编号 | 订单金额 | 商品编号 |
555555 | 1000 | 22 |
商品编号 | 商品名称 | 单价 |
22 | 耐克 | 100 |
外键: 引用另外一个表的记录,是关联表与表的字段
(1)外键列类型与主键类型一样
(2)数据表之间的关联靠主键与外键之间的依靠实现的
向某个suser表中添加专业编号,通过专业编号来关联专业信息
ALTER TABLE suser ADD COLUMN majorid INT
通过suser表中的专业id 可以关联到专业,majorid可以成为外键
-- 但是添加外键有俩种情况,一种是没有任何约束的外键,一种是添加了外键约束的外键
-- 无为外键约束关联,表与表之间3联,无外键约束的关联也称为弱关联
-- 无约束外键,删除主表(专业)信息时,没有任何的外键
-- 为外键列添加一个外键约束,那么 表与表之间就有强的约束关系
强关联的外键:
ALTER TABLE suser ADD CONSTRAINT majorid_fk FOREIGN KEY(majorid) REFERENCES major(id)
主表与从表: 添加外键的是从表
(1)当主表中没有对应记录时,不可以随便从从表中添加记录
(2)不能更改主表中的值从而导致从表中的信息孤立
(3)从表中存在与主表中的记录,不能从主表中删除对应的记录
(4)删除主表前,先删除从表
关联的关系种类:
(1)多对一,一对多 eg: 部门与员工之间的关系
(2)多对多 eg: 建立一个中间表用于关联俩表之间的联系
(3)一对一 eg: 一般用于多表的拆分,学生与详情
关联查询: 多表查询,当查询的字段来自于多个表中时,会用到连接查询
如果没有有效的连接条件,会初选笛卡尔乘积现象
按功能分类分为:
内连接 外连接
等值连接,非等值连接,自连接 左外连接,右外连接
等值连接:
SELECT a.sname,b.cname FROM suser a INNER JOIN major b ON a.majorid=b.id
表与表查询出来结果可能会有几个字段相同,几个字段内容不相同:
SELECT
s.id,s.name,s.gender,m.name,GROUP_CONCAT(c.name)-- 分组连接,把同一个组中的多个进行连接,只适用于多对多的情况
FROM -- 将不相同的字段进行拼接
suser s INNER JOIN major m ON s.id=m.id
INNER JOIN major_course mc ON m.id=mc.majorid
INNER JOIN course c ON mc.courseid=c.id
GROUP BY
s.name,s.id,s.gender -- 按相同的字段进行分组
左外,右外关联:
SELECT a.sname,b.cname FROM suser a LEFT JOIN major b ON a.majorid=b.id
SELECT a.sname,b.cname FROM suser a RIGHT JOIN major b ON a.majorid=b.id
非等值连接:
CREATE TABLE height(
nname VARCHAR(20),
low DOUBLE(3,2),
hei DOUBLE(3,2)
)
-- 非等值连接
SELECT s.name,s.gender FROM suser s INNER JOIN height h ON s.height BETWEEN h.low AND h.hei
自连接:
CREATE TABLE AREA(
id INT PRIMARY KEY,
NAME VARCHAR(20),
pid INT -- 父级id
)
SELECT * FROM AREA WHERE pid=0
SELECT * FROM AREA WHERE pid=610
SELECT * FROM AREA WHERE pid=61001
-- 自连接
SELECT * FROM AREA a1 INNER JOIN AREA a2 ON a1.pid=a2.id
INNER JOIN AREA a3 ON a2.pid=a3.id
WHERE a1.id = 61001
-- 条件是区级的区域,依次往上查询父级
子查询: 出现在其他语句中的select语句
子查询出现的位置:
(1)select后面:支持标量子查询
(2)支持标量子查询 from后面:支持表子查询
(3)支持表子查询 where:支持标量子查询,列子查询
列子查询 按功能、结果集的行列数不同:
(1)标量子查询(结果集只有一行一列)
(2)列子查询(结果集只有一列多行)
(3)表子查询(结果集一般为多行多列)