联系属性属于一段关系,不属于单独一端
以学生选课为例,成绩不是学生的固定属性。一个学生选不同课程,成绩不同;成绩也不是课程的固定属性,因为同一门课对不同学生成绩也不同。它真正属于“学生选某门课程”这个联系。
所以在多对多关系转换时,通常会建立选课表,里面保存学生编号、课程编号,以及成绩、选课时间等联系属性。这样每一行都能清楚表达:哪个学生、哪门课程、这次选课产生了什么数据。
| 场景 | 实体 | 联系 | 联系属性 |
|---|---|---|---|
| 学生选课 | 学生、课程 | 选课 | 成绩、选课时间 |
| 订单购买商品 | 订单、商品 | 购买明细 | 数量、成交单价 |
| 读者借阅图书 | 读者、图书 | 借阅 | 借阅日期、归还日期 |
| 员工参与项目 | 员工、项目 | 参与 | 角色、投入工时 |
多对多联系有属性:联系表几乎是必选动作
多对多本来就需要联系表;如果联系还有属性,联系表就更不能省。比如学生和课程之间的选课表,不只是用来解决多对多,还负责记录成绩、选课时间、重修标记等信息。
这类题的标准答案通常会长这样:选课(学号, 课程号, 成绩, 选课时间)。其中学号和课程号分别是外键,也常常共同组成主键或候选键。成绩这类联系属性,放在选课表里才有业务含义。
小例子:学生选课
学生(学号, 姓名, 班级)。
课程(课程号, 课程名, 学分)。
选课(学号, 课程号, 成绩, 选课时间)。
成绩跟某个学生和某门课同时有关,所以放在选课表。
一对多联系有属性,要看它能不能并入多端
如果是一对多联系,联系属性有时可以放到多端表里。比如客户和订单是一对多,订单日期、订单金额通常更像订单本身的属性,放在订单表里就很自然。因为每条订单记录已经对应一个客户,联系信息可以随订单一起保存。
但如果联系本身有独立含义,或者同一对实体之间会发生多次联系,就要考虑单独建联系表。比如员工参与项目,一名员工在同一项目中可能有多个阶段角色或多段投入记录,简单放在员工表或项目表都不合适。
| 联系类型 | 常见处理 | 提醒 |
|---|---|---|
| 一对多,联系属性与多端记录强绑定 | 通常放多端表 | 如订单日期放订单表 |
| 一对多,但联系可重复发生 | 考虑单独联系表 | 如多次借阅、阶段性参与 |
| 多对多,无论是否有属性 | 通常建联系表 | 两端主键进入联系表 |
| 联系属性很多且有生命周期 | 联系可能升级为实体 | 如合同、报名记录、借阅记录 |
考场上怎么不漏联系属性
读题时可以把属性逐个问一遍:它只描述学生吗?只描述课程吗?还是必须同时知道学生和课程才有意义?如果必须同时知道两端实体,它大概率是联系属性。
做关系模式转换时,别只写表名。至少要把主键、外键和联系属性写清楚。很多下午题丢分不是因为实体找错,而是关系表里少了成绩、数量、时间这类关键字段。
相关题目解析
下面这些题目和本专题的判断方法关联较强,适合读完概念后回到具体题干里校验理解。
- ER 图中的多对多联系转换成关系模式时怎么处理?ER 模型 / 多对多联系
- ER 图一对多联系转换成关系表时外键放在哪里?ER 图 / 关系模式转换
- 外键约束为什么能维护参照完整性?外键约束 / 参照完整性