表设计二,联接查询

Posted 稻草人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了表设计二,联接查询相关的知识,希望对你有一定的参考价值。

表设计

上一节我们说到,为了方便查看班级信息,我们将其独立了出来

但仔细思考一下,实际上学生和班级都是独立的个体,我们不能把班级的信息直接的放在学生身上,而是通过一个关系将它们串联在一起
学生离开了班级,它还是学生
班级离开了学生,它也还是班级
学生不会一辈子都是这个班级,而这个班级也不会一辈子只有这个学生
那是什么让它们之间相遇,就是一张纸上打印出来的名单

我们建立一张关系表Class_Student_Merge

字段名 主键 类型 占用字节数 长度 小数位数 允许空 默认值 字段说明
Id v uniqueidentifier (newid()) 主键
ClassId uniqueidentifier 班级Id
StudentId uniqueidentifier 学生Id

还是老样子,将我们Student的ClassId和Id转移到关系表中

 insert into Class_Student_Merge
 select newId(), ClassId, Id from Student


接下来把Student表中的ClassId列删除

此时Student的表结构为如下

这是目前
Class
Class_Student_Merge
Student
的关系图

看到这你会不会觉得很好奇,为什么要这样做,实际上凡事都是由两面性
好处是什么,我们的表就会少很多对自身描述无用的信息,从而做到信息关注点的侧重性,对自身进行分析和统计将会更加的方便
坏处是什么,就是数据太散了,查询和统计起来麻烦,相对于表设计一的两张表,而这种做法会变成三张表,增加维护性
所以一切以实际情况,自身情况而定,理论不能偏离实际,但是嘛咱们学习就得把难度往上加

那现在我们得怎么查询?
首先,我们得有个思路,多表联查最主要得就是要有出发点
比如我们从班级出发,班级外面贴着一张名单,名单里面标记了那些学生
按照这个思路,所以我们就这么查,班级关联名单,名单关联学生

select 
  class.[Name],
  stu.[Name] 
from Class as class
left join Class_Student_Merge as csm on class.Id = csm.ClassId
left join Student as stu on csm.StudentId = stu.Id
where class.[Name] = \'一年级\'

P.S:前面我们说到左连接,是根据左边主体数量而定,但是如果连接时发现右边有相同条件的数据,也会将其带出

这次我们换个情况,老师手上拿到一份名单,那要怎么去查班级和学生呢?
名单上既有班级又有学生,可纵可横,无论先关联谁都是可以的,不过建议先关联数据量少的,因为数据量少就可以更快的确定另一边的数据

select 
  class.[Name],
  stu.[Name]
from Class_Student_Merge as csm
left join Class as class on csm.ClassId= class.Id
left join Student as stu on csm.StudentId = stu.Id
where class.[Name] = \'一年级\'

总结:
多表联查,最主要就是摸出自己的路,但是实际上还是小心不要被别人坑了,毕竟认真思考和设计的人很少
一种是把关系放在自身内,一种是把关系单独拿出来,两种都是常见的做法,没有好坏之分

以上是关于表设计二,联接查询的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法改进这个查询

SQL语句汇总(终篇)—— 表联接与联接查询

数据库(比如MYSQL) ,表连结查询与子查询哪个效率高些? 为啥

使用子查询与派生表进行内部联接

10W学习笔记——查询之联接

联接表中的 JPQL 查询