数据库设计 · 多对多联系 · 联系表

多对多关系为什么要单独建表?

多对多关系单独建表,是数据库设计题里最稳定的高频点。很多同学知道结论,却说不清为什么。其实原因很简单:关系数据库表里的一个字段不应该塞一串重复值,多对多要靠一张联系表把两端实体一行一行对应起来。

数据库专题 软考题库编辑部 持续更新

多对多不能靠在一边塞字段解决

以学生选课为例,一个学生可以选多门课,一门课也可以被多个学生选择。如果把课程编号都塞进学生表的一个字段里,就会出现重复值、查询困难、更新麻烦等问题。

关系数据库更自然的做法,是建立一张“选课表”。每一行表示一个学生和一门课程之间的一次选择关系。这样既能表达多对多,也方便记录成绩、选课时间、任课教师等联系属性。

典型字段作用
学生表学生编号、姓名、班级保存学生实体属性
课程表课程编号、课程名、学分保存课程实体属性
选课表学生编号、课程编号、成绩、选课时间保存学生和课程之间的联系

联系表里放什么

联系表至少要包含两端实体的主键,通常作为外键引用原实体表。很多场景下,这两个外键还可以共同组成联合主键,表示同一个学生对同一门课程只能有一条选课记录。

如果联系本身有属性,也放在联系表里。比如学生选课关系里的成绩,不属于单纯的学生,也不属于单纯的课程,而是属于某个学生选某门课这件事。

两端主键学生编号、课程编号通常进入选课表
外键分别引用学生表和课程表
联系属性成绩、选课时间等放在联系表中

为什么这类题经常考学生选课、用户角色、订单商品

这些场景天然就是多对多:一个学生多门课,一门课多个学生;一个用户多个角色,一个角色多个用户;一个订单多个商品,一个商品也会出现在多个订单中。题干只要出现“两边都可以有多个”,就要警惕联系表。

老师讲题时常说一句:多对多不要硬塞到任意一端。硬塞会破坏数据规范性,也会让查询和维护变得很难。

考场判断口诀

一对多,外键放多端;多对多,单独建联系表;一对一,看约束和参与情况。这个口诀不复杂,但要能结合题干说出原因。

如果题目问“为什么不能把所有课程写在学生表一个字段中”,答案就要回到规范化和维护性:字段值不应重复堆叠,查询、插入、删除、修改都会变麻烦。

相关题目解析

下面这些题目和本专题的判断方法关联较强,适合读完概念后回到具体题干里校验理解。