从ER图到DDL:一个在线选课系统的数据库设计全流程复盘(避坑指南)
去年夏天,我们团队接手了一个高校在线选课系统的开发项目。作为负责数据库设计的工程师,我本以为凭借教科书上的ER图转换规则就能轻松完成任务,没想到从第一版ER图到最终可执行的DDL语句,整整经历了三次推翻重来。本文将用真实项目中的踩坑经历,还原一个中小型系统数据库设计的完整决策过程,特别适合那些已经掌握数据库基础理论,但缺乏实战经验的中级开发者。
1. 需求分析与第一版ER图的致命缺陷
客户最初提供的需求文档只有三页纸,核心功能包括:学生选课、教师开课、成绩录入。我们花了三天时间与教务处老师深入沟通,才发现隐藏的业务规则:
- 同一门课程每年可能有多个教学班(section),每个教学班由不同教师授课
- 学生可以退选课程,但开课两周后不允许再退选
- 某些课程有先修课程要求,必须按顺序修读
第一版ER图的主要问题:
mermaid复制erDiagram
STUDENT ||--o{ COURSE : selects
TEACHER ||--o{ COURSE : teaches
COURSE ||--o{ PREREQ : requires
这个简陋的ER图至少存在三个严重缺陷:
- 多对多关系未拆解:学生与课程之间实际是多对多关系(一个学生选多门课,一门课被多个学生选),但图中错误地用一对多表示
- 缺失关键实体:完全忽略了"教学班"这个核心概念,导致无法记录同一课程不同教师/时间段的开课信息
- 属性分配不当:将成绩属性直接放在课程实体,无法记录同一课程不同学期的成绩
关键教训:需求分析阶段一定要找出所有业务实体和它们之间的基数关系。我们后来采用的方法是让客户描述5个典型用户操作流程,从中提取实体和关系。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 关系模式转换中的典型陷阱
第二版ER图完善了实体和关系,但在转换为关系模式时又遇到新问题:
2.1 多对多关系的中间表遗漏
最初的"学生-课程"多对多关系直接转换为:
sql复制CREATE TABLE student_course (
student_id INT,
course_id INT,
PRIMARY KEY (stu
