表设计
上一节我们说到,为了方便查看班级信息,我们将其独立了出来
但仔细思考一下,实际上学生和班级都是独立的个体,我们不能把班级的信息直接的放在学生身上,而是通过一个关系将它们串联在一起
学生离开了班级,它还是学生
班级离开了学生,它也还是班级
学生不会一辈子都是这个班级,而这个班级也不会一辈子只有这个学生
那是什么让它们之间相遇,就是一张纸上打印出来的名单
我们建立一张关系表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] = '一年级'
总结:
多表联查,最主要就是摸出自己的路,但是实际上还是小心不要被别人坑了,毕竟认真思考和设计的人很少
一种是把关系放在自身内,一种是把关系单独拿出来,两种都是常见的做法,没有好坏之分
下一节子查询