一、引言
提到查询,我们想到之前学习的单表查询(DQL语句)。而这一章节部分的博客我们将要去学习和了解多表查询。
对于多表查询,主要从以下7个方面进行学习。
(1)第一部分:介绍
1、多表关系
2、多表查询的概念以及多表查询的分类
(2)第二部分:然后接下来针对于多表查询所涉及到的
3、内连接
4、外连接
5、自连接
6、子查询
(3)第三部分:讲解完之后再通过一个多表查询的案例,对多表查询的语法进行巩固和加强
7、多表查询案例
二、多表关系
- 概述
在项目开发中,在进行数据库表结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结构。由于业务之间相互关联(错综复杂),所以我们所设计出来的各个表结构之间也存在着各种各样的联系。而这种联系基本上分为三种:
1、一对多(多对一)
2、多对多
3、一对一
这三种联系代表了什么含义?以及在数据库层面怎么去体现这些联系或者关系呢?下面将会详细的介绍这三种多表关系。
(1)一对多(多对一)
比较典型的案例:部门与员工的关系
关系:一个部门下可以对应着多个员工,而一个员工对应一个部门
问题:在员工和部门的关系中,其中谁是 '多' 的一方呢?谁又是 '一' 的一方?
结论:部门是 '一' 的一方,而员工表是 '多' 的一方
实现方法:
在这种一对多的关系中,在数据库层面,我们要体现出这种关系。
通常是:在'多'的一方建立一个外键,这个外键来关联 '一' 的一方的主键。
这个案例之前在外键约束的案例就演示过了。
(2)多对多
比较典型的案例:学生与课程之间的关系
关系:一个学生可以选修多门课程,一门课程也可以供多个学生选择
问题:那么我们如何来维护他们之间的 '多对多' 的关系呢?
实现方法:
此时需要建立第三张表。建立第三张中间表,其中中间表至少要包含两个外键,分别关联两方的主键。
接下来去到工具 DataGrip 对这个案例进行实操。
1、三张表的结构创建、以及插入数据
学生表:student
CREATE TABLE student ( id INT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID', name VARCHAR(10) COMMENT '姓名', no VARCHAR(10) COMMENT '学号' ) COMMENT '学生表'; INSERT INTO student (id, name, no) VALUES (null,'黛绮丝','2000100101'), (null,'谢逊','2000100102'), (null,'阳俊毅','2000100103'), (null,'韦一敏','2000100104');
课程表:course
CREATE TABLE course ( id INT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID', name VARCHAR(10) COMMENT '课程名称' ) COMMENT '课程表'; INSERT INTO course(id, name) VALUES (null,'Java'), (null,'PHP'), (null,'MySQL'), (null,'C++');
目前两张表还未建立任何的关联。他们之间是多对多的关系,所以我们要再建立一张中间表去维护他们之间的关系,下面进行创建。
2、续集第一部操作
CREATE TABLE student_course ( id INT AUTO_INCREMENT COMMENT '主键' PRIMARY KEY, student_id INT NOT NULL COMMENT '学生ID', course_id INT NOT NULL COMMENT '课程ID', /*建立两个外键 ,对应两个主表*/ CONSTRAINT fk_course_id FOREIGN KEY (course_id) REFERENCES course(id), CONSTRAINT fk_student_id FOREIGN KEY (student_id) REFERENCES student(id) ) COMMENT '学生课程中间表'; INSERT INTO student_course(ID, STUDENT_ID, COURSE_ID) VALUES (null,1,1), (null,1,2), (null,1,3), (null,2,2), (null,2,3), (null,3,4);
查看表
这就是多对多的关系在数据库层面的体现,通过中间表来维护。
3、此时我们可以通过工具 DataGrip 直接可视化界面的形式展示三个表之间的多表关系
(3) 一对一
比较典型的案例:用户与用户详情的关系
关系:一对一关系,经常用于单表拆分。
将一张表的基础字段放在一张表中,其他详情字段放在另一张表中,以提升操作效率。
比如下面有张表用户表:
问题:这张表的数据虽然很全,但是因为数据信息比较庞大,我们要根据有些业务场景中需求进行一些拆分。就比如有时候我们只需要查询用户的一些基本信息?在某些场景下我们又需要查询用户的受教育的信息?还有如何维护拆分之后的两张表的关系?
实现方法:此时,我们就可以将这个表进行拆分。把基础的用户字段放在一张表中,把用户受教育的信息放在另外一张表中。拆分了之后,我们还得考虑其它情况。比如如何继续维护这两张表的关系。在任意的一张表加入一个外键,去关联另一张表的主键就可以了。
也就是注意:
在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一的(UNIQUE)。这个又好像和一对多比较像,所以此时为了限定它们之间是一对一的关系,则需要在外键上再添加一个唯一约束,也就意味着教育信息的一条记录只能对应着一个用户。从而保证它们是一对一的关系。
接下来去到工具 DataGrip 对这个案例进行实操。
1、创建两张表的结构
2、插入数据
用户基本表
教育信息表
所以一条教育信息,对应一个用户
这篇博客的内容就到这里了。