规范化考试题目数据表以实现父题与子题的关联
考试题与子题的最优关系型数据库Schema设计
现有结构的问题
你当前的设计用isSubQ标记子题、part存所属部分,存在以下冗余和风险:
isSubQ属于冗余字段,可被更明确的关联逻辑替代- 没有建立父题与子题的直接绑定关系,仅靠
part无法保证数据一致性,容易出现子题归属混乱 part作为可选字段,可能存在子题缺失归属标识的情况,破坏业务逻辑
最佳方案:自关联外键设计
在题目表中新增parent_id字段,作为外键指向本表的ID主键,以此建立父题与子题的明确关联。同时简化冗余字段,具体Schema结构如下:
| 字段名 | 类型说明 | 备注 |
|---|---|---|
ID | 主键(整数/UUID) | 题目的唯一标识 |
Number | 字符串/整数 | 题目编号,父题可用主编号(如3),子题可扩展为3a/3b或保留主编号配合part区分 |
Max | 数值类型(如DECIMAL) | 该题的满分分值 |
Text | 文本类型(如TEXT) | 题目描述文本 |
parent_id | 外键,允许为空,指向ID | 父题的ID;若为NULL则表示当前是父题,否则为子题所属的父题ID |
part | 字符串(可选) | 子题的部分标识(如a、b、c),用于区分同一父题下的不同子题 |
exam | 外键,关联考试表ID | 所属考试的ID |
示例数据(对应你提到的第3题含a/b/c子题)
父题(第3题)
ID: 101Number: "3"Max: 15(若父题仅做分组用,可设为0,子题分值总和为15)Text: "第3题:请完成以下各部分作答"parent_id: NULLpart: NULLexam: 2024001
子题3a
ID: 102Number: "3a"Max: 5Text: "a部分:简述XX核心概念"parent_id: 101part: "a"exam: 2024001
子题3b
ID: 103Number: "3b"Max: 5Text: "b部分:分析XX实际案例"parent_id: 101part: "b"exam: 2024001
子题3c
ID: 104Number: "3c"Max: 5Text: "c部分:提出XX解决方案"parent_id: 101part: "c"exam: 2024001
该设计的优势
- 消除冗余:无需
isSubQ字段,通过parent_id是否为空即可判断题目类型(父/子) - 关联清晰:外键约束保证子题必然归属一个合法的父题,避免数据混乱
- 扩展性强:支持多级嵌套子题(如子题下再设子子题),只需将
parent_id指向上层题目ID即可 - 查询高效:通过JOIN操作可快速获取某父题下所有子题,或某子题的父题,配合索引性能更优
- 约束灵活:可添加数据库约束(如触发器或检查约束),确保子题的
exam与父题一致,避免跨考试关联
内容的提问来源于stack exchange,提问作者Rohit Manjunath
相关产品推荐
相关产品推荐

