# 学生管理系统 — 数据库设计文档 ## 1. 数据库概述 | 属性 | 说明 | |------|------| | 数据库名 | `sms`(学生管理系统 Student Manage System) | | 存储引擎 | InnoDB | | 字符集 | utf8mb4 | | 默认排序规则 | utf8mb4_unicode_ci | | 通用字段方案 | `id`、`create_time`、`update_time`、`is_deleted`、`delete_time` | --- ## 2. ER 关系图 ``` ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ teachers │ │ classes │ │ students │ ├──────────────────┤ ├──────────────────┤ ├──────────────────┤ │ id (PK) │ │ id (PK) │ │ id (PK) │ │ num (UK) │ │ num (UK) │ │ num (UK) │ │ name │ 1:N │ name │ 1:N │ name │ │ age │ ----> │ class_start_time │ ----> │ age │ │ sex │ │ │ │ sex │ │ home_place │ │ head_teacher_id │ │ home_place │ │ college │ │ coach_teacher_id │ │ college │ │ specialty │ │ tutor_teacher_id │ │ specialty │ │ enrollment_time │ └──────┬───────────┘ │ enrollment_time │ │ graduate_time │ │ graduate_time │ │ education │ │ education │ │ work_experience │ │ │ │ coach_area │ │ create_time │ │ │ │ update_time │ │ create_time │ ------------------│ is_deleted │ │ update_time │ │ │ delete_time │ │ is_deleted │ │ 1:N └──────────────────┘ │ delete_time │ ▼ | 1:1 └──────────────────┘ ┌──────────────────┐ ┌──────────────────┐ │ scores │ │ employment │ ├──────────────────┤ ├──────────────────┤ │ id (PK) │ │ id (PK) │ │ sid (FK→students)│ │ sid (FK→students)│ │ num │ │ class_id (FK) │ │ score │ │ employment_open │ │ │ │ _time │ │ create_time │ │ offer_recived │ │ update_time │ │ _time │ │ is_deleted │ │ employment_comp │ │ delete_time │ │ any │ └──────────────────┘ │ employment_salar │ │ y │ │ │ │ create_time │ │ update_time │ │ is_deleted │ │ delete_time │ └──────────────────┘ ``` --- ## 3. 表结构详述 ### 3.1 teachers — 教师表 | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | INT | PK, AUTO_INCREMENT | 主键 | | num | VARCHAR(30) | UNIQUE, NOT NULL, INDEX | 教师编号 | | name | VARCHAR(30) | NOT NULL | 姓名 | | age | INT | DEFAULT 18 | 年龄 | | sex | INT | DEFAULT 0 | 性别:0未知 1男 2女 | | home_place | VARCHAR(50) | NULL | 家乡 | | college | VARCHAR(50) | NULL | 毕业院校 | | specialty | VARCHAR(50) | NULL | 专业 | | enrollment_time | DATETIME | NULL | 入学时间 | | graduate_time | DATETIME | NULL | 毕业时间 | | education | VARCHAR(50) | NULL | 学历 | | work_experience | TEXT | NULL | 工作经验 | | coach_area | VARCHAR(50) | NULL | 教学方向:应用/项目/算法 | | create_time | DATETIME | NOT NULL | 创建时间 | | update_time | DATETIME | NOT NULL | 更新时间 | | is_deleted | BOOLEAN | DEFAULT FALSE | 软删除标志 | | delete_time | DATETIME | NULL | 删除时间 | **索引:** ```sql PRIMARY KEY (id), UNIQUE KEY uk_tnum (num), KEY idx_num (num) ``` **外键:** 无(teachers 作为被引用方) --- ### 3.2 classes — 班级表 | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | INT | PK, AUTO_INCREMENT | 主键 | | num | VARCHAR(30) | UNIQUE, NOT NULL, INDEX | 班级编号 | | name | VARCHAR(30) | NOT NULL | 班级名称 | | class_start_time | DATETIME | NULL | 开课时间 | | head_teacher_id | INT | NULL, FK→teachers.id | 班主任 ID | | coach_teacher_id | INT | NULL, FK→teachers.id | 授课老师 ID | | tutor_teacher_id | INT | NULL, FK→teachers.id | 助教老师 ID | | create_time | DATETIME | NOT NULL | 创建时间 | | update_time | DATETIME | NOT NULL | 更新时间 | | is_deleted | BOOLEAN | DEFAULT FALSE | 软删除标志 | | delete_time | DATETIME | NULL | 删除时间 | **索引:** ```sql PRIMARY KEY (id), UNIQUE KEY uk_class_num (num), KEY idx_head_teacher (head_teacher_id), KEY idx_coach_teacher (coach_teacher_id), KEY idx_tutor_teacher (tutor_teacher_id) ``` **外键:** ```sql CONSTRAINT fk_classes_head_teacher FOREIGN KEY (head_teacher_id) REFERENCES teachers(id) ON DELETE SET NULL ON UPDATE CASCADE, CONSTRAINT fk_classes_coach_teacher FOREIGN KEY (coach_teacher_id) REFERENCES teachers(id) ON DELETE SET NULL ON UPDATE CASCADE, CONSTRAINT fk_classes_tutor_teacher FOREIGN KEY (tutor_teacher_id) REFERENCES teachers(id) ON DELETE SET NULL ON UPDATE CASCADE ``` --- ### 3.3 students — 学生表 | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | INT | PK, AUTO_INCREMENT | 主键 | | num | VARCHAR(30) | UNIQUE, NOT NULL, INDEX | 学生编号 | | name | VARCHAR(30) | NOT NULL | 姓名 | | age | INT | DEFAULT 18 | 年龄 | | sex | INT | DEFAULT 0 | 性别:0未知 1男 2女 | | home_place | VARCHAR(50) | NULL | 家乡 | | college | VARCHAR(50) | NULL | 毕业院校 | | specialty | VARCHAR(50) | NULL | 专业 | | enrollment_time | DATETIME | NULL | 入学时间 | | graduate_time | DATETIME | NULL | 毕业时间 | | education | VARCHAR(50) | NULL | 学历 | | class_id | INT | NOT NULL, DEFAULT 0, INDEX | 所属班级 ID | | advisor_id | INT | NULL, FK→teachers.id | 顾问老师 ID | | create_time | DATETIME | NOT NULL | 创建时间 | | update_time | DATETIME | NOT NULL | 更新时间 | | is_deleted | BOOLEAN | DEFAULT FALSE | 软删除标志 | | delete_time | DATETIME | NULL | 删除时间 | **索引:** ```sql PRIMARY KEY (id), UNIQUE KEY uk_snum (num), KEY idx_class_id (class_id), KEY idx_advisor_id (advisor_id), KEY idx_class_deleted (class_id, is_deleted) -- 复合索引,优化班级学生列表查询 ``` **外键:** ```sql CONSTRAINT fk_students_class FOREIGN KEY (class_id) REFERENCES classes(id) ON DELETE RESTRICT ON UPDATE CASCADE, CONSTRAINT fk_students_advisor FOREIGN KEY (advisor_id) REFERENCES teachers(id) ON DELETE SET NULL ON UPDATE CASCADE ``` > **注意**:`class_id` 使用 `ON DELETE RESTRICT`,防止误删有学生的班级。 --- ### 3.4 scores — 成绩表 | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | INT | PK, AUTO_INCREMENT | 主键 | | sid | INT | NOT NULL, FK→students.id, INDEX | 学生 ID | | num | VARCHAR(30) | NOT NULL | 考核序次(如"第一次考核") | | score | DECIMAL(10,2) | NOT NULL | 分数 | | create_time | DATETIME | NOT NULL | 创建时间 | | update_time | DATETIME | NOT NULL | 更新时间 | | is_deleted | BOOLEAN | DEFAULT FALSE | 软删除标志 | | delete_time | DATETIME | NULL | 删除时间 | **索引:** ```sql PRIMARY KEY (id), UNIQUE KEY uk_sid_score (sid, num), -- 防止同一学生同一考核重复录入 KEY idx_sid (sid) ``` **外键:** ```sql CONSTRAINT fk_scores_student FOREIGN KEY (sid) REFERENCES students(id) ON DELETE CASCADE ON UPDATE CASCADE ``` > 删除学生时,其所有成绩记录自动级联删除。 --- ### 3.5 employment — 就业表 | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | INT | PK, AUTO_INCREMENT | 主键 | | sid | INT | UNIQUE, FK→students.id | 学生 ID(一对一) | | class_id | INT | NOT NULL, INDEX | 所属班级 ID | | employment_open_time | DATETIME | NULL | 就业开放时间 | | offer_recived_time | DATETIME | NULL | Offer 下发时间 | | employment_company | VARCHAR(50) | NULL | 就业公司 | | employment_salary | DECIMAL(20,5) | NULL | 就业薪资(月薪) | | create_time | DATETIME | NOT NULL | 创建时间 | | update_time | DATETIME | NOT NULL | 更新时间 | | is_deleted | BOOLEAN | DEFAULT FALSE | 软删除标志 | | delete_time | DATETIME | NULL | 删除时间 | **索引:** ```sql PRIMARY KEY (id), UNIQUE KEY uk_sid (sid), -- 一名学生只允许一条就业记录 KEY idx_class_id (class_id), KEY idx_class_deleted (class_id, is_deleted) -- 复合索引,优化班级就业统计 ``` **外键:** ```sql CONSTRAINT fk_employment_student FOREIGN KEY (sid) REFERENCES students(id) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT fk_employment_class FOREIGN KEY (class_id) REFERENCES classes(id) ON DELETE RESTRICT ON UPDATE CASCADE ``` --- ## 4. 完整 DDL(可直接执行) ```sql CREATE DATABASE IF NOT EXISTS sms CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE sms; -- ==================== teachers ==================== CREATE TABLE IF NOT EXISTS teachers ( id INT AUTO_INCREMENT PRIMARY KEY, num VARCHAR(30) NOT NULL COMMENT '教师编号', name VARCHAR(30) NOT NULL DEFAULT '' COMMENT '姓名', age INT NOT NULL DEFAULT 18 COMMENT '年龄', sex INT NOT NULL DEFAULT 0 COMMENT '性别:0未知 1男 2女', home_place VARCHAR(50) NULL COMMENT '家乡', college VARCHAR(50) NULL COMMENT '毕业院校', specialty VARCHAR(50) NULL COMMENT '专业', enrollment_time DATETIME NULL COMMENT '入学时间', graduate_time DATETIME NULL COMMENT '毕业时间', education VARCHAR(50) NULL COMMENT '学历', work_experience TEXT NULL COMMENT '工作经验', coach_area VARCHAR(50) NULL COMMENT '教学方向:应用/项目/算法', create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, is_deleted TINYINT(1) NOT NULL DEFAULT 0, delete_time DATETIME NULL, UNIQUE KEY uk_tnum (num), KEY idx_num (num) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='教师表'; -- ==================== classes ==================== CREATE TABLE IF NOT EXISTS classes ( id INT AUTO_INCREMENT PRIMARY KEY, num VARCHAR(30) NOT NULL COMMENT '班级编号', name VARCHAR(30) NOT NULL COMMENT '班级名称', class_start_time DATETIME NULL COMMENT '开课时间', head_teacher_id INT NULL COMMENT '班主任ID', coach_teacher_id INT NULL COMMENT '授课老师ID', tutor_teacher_id INT NULL COMMENT '助教老师ID', create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, is_deleted TINYINT(1) NOT NULL DEFAULT 0, delete_time DATETIME NULL, UNIQUE KEY uk_class_num (num), KEY idx_head_teacher (head_teacher_id), KEY idx_coach_teacher (coach_teacher_id), KEY idx_tutor_teacher (tutor_teacher_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='班级表'; ALTER TABLE classes ADD CONSTRAINT fk_classes_head_teacher FOREIGN KEY (head_teacher_id) REFERENCES teachers(id) ON DELETE SET NULL ON UPDATE CASCADE, ADD CONSTRAINT fk_classes_coach_teacher FOREIGN KEY (coach_teacher_id) REFERENCES teachers(id) ON DELETE SET NULL ON UPDATE CASCADE, ADD CONSTRAINT fk_classes_tutor_teacher FOREIGN KEY (tutor_teacher_id) REFERENCES teachers(id) ON DELETE SET NULL ON UPDATE CASCADE; -- ==================== students ==================== CREATE TABLE IF NOT EXISTS students ( id INT AUTO_INCREMENT PRIMARY KEY, num VARCHAR(30) NOT NULL COMMENT '学生编号', name VARCHAR(30) NOT NULL DEFAULT '' COMMENT '姓名', age INT NOT NULL DEFAULT 18 COMMENT '年龄', sex INT NOT NULL DEFAULT 0 COMMENT '性别:0未知 1男 2女', home_place VARCHAR(50) NULL COMMENT '家乡', college VARCHAR(50) NULL COMMENT '毕业院校', specialty VARCHAR(50) NULL COMMENT '专业', enrollment_time DATETIME NULL COMMENT '入学时间', graduate_time DATETIME NULL COMMENT '毕业时间', education VARCHAR(50) NULL COMMENT '学历', class_id INT NOT NULL DEFAULT 0 COMMENT '所属班级ID', advisor_id INT NULL COMMENT '顾问老师ID', create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, is_deleted TINYINT(1) NOT NULL DEFAULT 0, delete_time DATETIME NULL, UNIQUE KEY uk_snum (num), KEY idx_class_id (class_id), KEY idx_advisor_id (advisor_id), KEY idx_class_deleted (class_id, is_deleted) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='学生表'; ALTER TABLE students ADD CONSTRAINT fk_students_class FOREIGN KEY (class_id) REFERENCES classes(id) ON DELETE RESTRICT ON UPDATE CASCADE, ADD CONSTRAINT fk_students_advisor FOREIGN KEY (advisor_id) REFERENCES teachers(id) ON DELETE SET NULL ON UPDATE CASCADE; -- ==================== scores ==================== CREATE TABLE IF NOT EXISTS scores ( id INT AUTO_INCREMENT PRIMARY KEY, sid INT NOT NULL COMMENT '学生ID', num VARCHAR(30) NOT NULL COMMENT '考核序次', score DECIMAL(10,2) NOT NULL COMMENT '分数', create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, is_deleted TINYINT(1) NOT NULL DEFAULT 0, delete_time DATETIME NULL, UNIQUE KEY uk_sid_score (sid, num), KEY idx_sid (sid) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='成绩表'; ALTER TABLE scores ADD CONSTRAINT fk_scores_student FOREIGN KEY (sid) REFERENCES students(id) ON DELETE CASCADE ON UPDATE CASCADE; -- ==================== employment ==================== CREATE TABLE IF NOT EXISTS employment ( id INT AUTO_INCREMENT PRIMARY KEY, sid INT NOT NULL COMMENT '学生ID', class_id INT NOT NULL COMMENT '班级ID', employment_open_time DATETIME NULL COMMENT '就业开放时间', offer_recived_time DATETIME NULL COMMENT 'Offer下发时间', employment_company VARCHAR(50) NULL COMMENT '就业公司', employment_salary DECIMAL(20,5) NULL COMMENT '就业薪资(月薪)', create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, is_deleted TINYINT(1) NOT NULL DEFAULT 0, delete_time DATETIME NULL, UNIQUE KEY uk_sid (sid), KEY idx_class_id (class_id), KEY idx_class_deleted (class_id, is_deleted) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='就业表'; ALTER TABLE employment ADD CONSTRAINT fk_employment_student FOREIGN KEY (sid) REFERENCES students(id) ON DELETE CASCADE ON UPDATE CASCADE, ADD CONSTRAINT fk_employment_class FOREIGN KEY (class_id) REFERENCES classes(id) ON DELETE RESTRICT ON UPDATE CASCADE; ``` --- ## 5. 索引设计说明 | 表 | 索引名 | 类型 | 字段 | 优化场景 | |----|--------|------|------|----------| | students | uk_snum | 唯一 | num | 按学号精确查询 | | students | idx_class_id | 普通 | class_id | 按班级查学生列表 | | students | idx_advisor_id | 普通 | advisor_id | 按顾问查学生 | | students | idx_class_deleted | 联合 | (class_id, is_deleted) | 查某班未删除学生(覆盖常见过滤) | | classes | uk_class_num | 唯一 | num | 按班级编号精确查询 | | classes | idx_head_teacher | 普通 | head_teacher_id | 按班主任查班级 | | scores | uk_sid_score | 唯一 | (sid, num) | 防止重复录入,加速组合查询 | | scores | idx_sid | 普通 | sid | 按学生查成绩 | | employment | uk_sid | 唯一 | sid | 保证一人一条就业记录 | | employment | idx_class_id | 普通 | class_id | 按班级统计就业 | | employment | idx_class_deleted | 联合 | (class_id, is_deleted) | 班级就业统计过滤已删除记录 | --- ## 6. 数据字典表(V2.0 规划) ```sql CREATE TABLE IF NOT EXISTS dict_items ( id INT AUTO_INCREMENT PRIMARY KEY, dict_type VARCHAR(50) NOT NULL COMMENT '字典类型:sex, education, college, specialty, coach_area', dict_code VARCHAR(50) NOT NULL COMMENT '字典编码,业务表存储的值', dict_label VARCHAR(100) NOT NULL COMMENT '显示名称', sort_order INT NOT NULL DEFAULT 0 COMMENT '排序权重', is_enabled TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否启用', create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, is_deleted TINYINT(1) NOT NULL DEFAULT 0, delete_time DATETIME NULL, UNIQUE KEY uk_type_code (dict_type, dict_code), KEY idx_type (dict_type) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='通用字典表'; -- 初始数据 INSERT INTO dict_items (dict_type, dict_code, dict_label, sort_order) VALUES ('sex', '0', '未知', 1), ('sex', '1', '男', 2), ('sex', '2', '女', 3), ('education','bachelor', '本科', 1), ('education','master', '硕士', 2), ('education','phd', '博士', 3), ('coach_area','app', '应用', 1), ('coach_area','project', '项目', 2), ('coach_area','algorithm','算法', 3); ``` **引用方式(应用层 JOIN):** ```sql -- 查询学生时关联字典获取可读名称 SELECT s.*, d_sex.dict_label AS sex_label, d_edu.dict_label AS education_label FROM students s LEFT JOIN dict_items d_sex ON d_sex.dict_type='sex' AND d_sex.dict_code=CAST(s.sex AS CHAR) LEFT JOIN dict_items d_edu ON d_edu.dict_type='education' AND d_edu.dict_code=s.education WHERE s.is_deleted=0; ``` --- ## 7. 历史数据归档策略(V3.0 规划) 当数据量达到千万级时,考虑以下归档方案: | 策略 | 适用场景 | 说明 | |------|----------|------| | 分区表(PARTITION BY RANGE) | 按年份归档 | 对 `create_time` 做范围分区,老分区可迁移至冷存储 | | 归档表(_history 后缀) | 毕业生数据 | 将已毕业学生的成绩/就业记录移入 `students_history` 等归档表 | | 分库分表 | 超大规模 | 按 `class_id` 哈希分片,需引入 ShardingSphere 或应用层分片 | **归档判断条件:** - 学生 `graduate_time` 距今超过 2 年 - 或主动标记为"已归档"状态