多表关系
在进行数据库表结构的设计时,会根据业务的需求和业务模块之间的关系,分析设计表结构,由于业务之间相互关联,所以各个表结构之间也存在各种联系
表与表之间的联系:
1.一对多(多对一)
2.多对多
3.一对一
一对多(多对一)
例如,一个员工对应一个部门,一个部门可以对应多个员工
一般在多的一方创建外键,指向一的那一方
员工与部门,在员工表上设置外键,指向部门表
多对多
例如,一个学生可以选修多门课程,一个课程可以被多名学生选修
一般会建立第三张表,至少包含两个外键,分别指向两张表的主键
一对一
例如,用户和自己的学历信息的关系,一个人只对应一条学历信息
可以在任意一方加入外键,关联另一方的主键,并且设置外键为唯一(unique)
注:可以放在一张表中,但是对其进行拆分,一张表放基础信息,另一张表放详情,可以提升操作效率
多表查询
概述:
从多张表中查询数据
笛卡尔积:
笛卡尔积为两个集合(两张表)中的每条数据进行两两组合的结果
在多表查询时会产生笛卡尔积,要通过添加条件消除笛卡尔积
dept表:
emp表:
查询产生笛卡尔积的结果:
select * from emp, dept ; • 1
消除笛卡尔积(添加条件):
select * from emp, dept where emp.dept_id=dept.id; • 1
多表查询的分类
1.连接查询:
内连接: 相当于查询AB的交集部分 外连接: 左外连接: 查询A的所有数据,同时拼接上B对应的数据 右外连接: 查询B的所有数据,同时拼接上A中对应的数据 自连接: 表与自身连接查询 自连接必须给表取别名
2.子查询
数据准备
部门表:
create table dept ( id int auto_increment primary key comment 'id', name varchar(50) not null comment '部门名称' ) comment '部门表'; insert into dept (id, name) values (1, '研发部'), (2, '市场部'), (3, '财务部'), (4, '销售部'), (5, '总经办'), (6, '人事部');
员工表:
create table emp( id int auto_increment primary key , name varchar(50) not null , age int, job varchar(20) comment '职位', salary int , entrydate date comment '入职时间', managerid int comment '直属领导id', dept_id int comment '所在部门id' ) comment '员工表'; insert into emp values ( 1, '金庸', 66, '总裁', 20000, '2000-01-01', null, 5 ), ( 2, '张无忌', 20, '项目经理', 12500, '2005-12-05', 1, 1 ), ( 3, '杨晓', 33, '开发', 8400, '2000-11-03', 2, 1 ), ( 4, '韦一笑', 48, '开发', 11000, '2002-02-05', 2, 1 ), ( 5, '陈玉存', 43, '开发', 10500, '2004-09-07', 3, 1 ), ( 6, '小昭', 19, '程序员鼓励师', 6600, '2004-10-12', 2, 1 ), ( 7, '灭绝', 60, '财务总监', 8500, '2002-09-12', 1, 3 ), ( 8, '周芷若', 19, '会计', 48000, '2006-06-02', 7, 3 ), ( 9, '丁敏君', 23, '出纳', 5250, '2009-05-13', 7, 3 ), ( 10, '赵敏', 20, '市场部总监', 12500, '2004-10-12', 1, 2 ), ( 11, '鹿杖客', 56, '职员', 3750, '2006-10-03', 10, 2 ), ( 12, '何碧文', 19, '职员', 3750, '2007-05-09', 10, 2 ), ( 13, '东方白', 19, '职员', 5500, '2009-02-12', 10, 2 ), ( 14, '张三丰', 88, '销售总监', 14000, '2004-10-12', 1, 4 ), ( 15, '鱼梁洲', 38, '销售', 4600, '2004-10-12', 14, 4 ), ( 16, '宋远桥', 40, '销售', 4600, '2004-10-12', 14, 4 ), ( 17, '陈友谅', 42, null, 2000, '2011-10-12', 1, null )
内连接
语法:
# 隐式内连接 select 字段列表 from 表1,表2 where 条件; # 显示内连接 select 字段列表 from 表1 [inner] join 表2 on 连接条件;
内连接查询的是两张表交集的部分
# 查询每一个员工的姓名及关联的部门的名称 select emp.name, dept.name from emp, dept where emp.dept_id=dept.id; select emp.name, dept.name from emp inner join dept on emp.dept_id = dept.id;