学生管理系统不是“先建库再写代码”的线性任务,核心在于数据关系是否能真实反映业务约束——比如一个学生不能同时属于两个院系,一门课不能没有授课教师。设计阶段漏掉这些,后期靠应用层补救只会越来越难。
学生、课程、成绩三张表的主外键怎么连才不翻车
常见错误是把
student_id和
course_id直接塞进成绩表却不加约束,导致插入不存在的学生或课程记录也能成功。必须用外键强制关联:
score表的
student_id字段要
REFERENCES student(id),且
ON DELETE CASCADE(删学生自动清成绩)
score表的
course_id字段要
REFERENCES course(id),但通常不级联删,避免误删课程后成绩丢失 所有外键字段类型必须严格一致:比如
student.id是
BIGINT UNSIGNED,
score.student_id也得是这个类型,否则 MySQL 拒绝建外键
院系、专业、班级三级结构该不该拆成三张表
拆还是不拆,取决于查询频率和变更粒度。如果专业名称几乎不变、班级每学期新建,而经常要查“计算机学院下所有软件工程专业的班级”,那就值得拆:
department表存学院,
id+
name
major表存专业,带
dept_id外键指向院系
class表存班级,带
major_id外键指向专业 反例:全塞进一张
class表,用
dept_name、
major_name字符串冗余存储——更新专业名时要批量 UPDATE,极易漏改或出错
成绩字段用 DECIMAL 还是 FLOAT
必须用
DECIMAL(5,2),别碰
FLOAT。原因很实际:
FLOAT是二进制浮点,
95.5可能存成
95.49999999999999,排序、求平均时出现肉眼可见的偏差
DECIMAL(5,2)表示最多 5 位数字、小数点后 2 位,够覆盖 0–100 分且精确到百分位 别写
DECIMAL(10,2)—— 无意义地浪费存储,InnoDB 行格式对 DECIMAL 长度敏感
真正卡住开发进度的,往往不是语法不会写,而是建表时没想清楚“谁删了谁会跟着删”“哪个字段改一次要波及多少行”。这些细节在 ER 图里画两笔,在 SQL 里加几个约束,比后期写一堆校验逻辑省心得多。
