Files
student_manage_system/docs/03-database-design.md
T
2026-09-23 10:43:14 +08:00

20 KiB
Raw Blame History

学生管理系统 — 数据库设计文档

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 删除时间

索引:

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 删除时间

索引:

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)

外键:

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 删除时间

索引:

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)  -- 复合索引,优化班级学生列表查询

外键:

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 删除时间

索引:

PRIMARY KEY (id),
UNIQUE KEY uk_sid_score (sid, num),  -- 防止同一学生同一考核重复录入
KEY idx_sid (sid)

外键:

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 删除时间

索引:

PRIMARY KEY (id),
UNIQUE KEY uk_sid (sid),           -- 一名学生只允许一条就业记录
KEY idx_class_id (class_id),
KEY idx_class_deleted (class_id, is_deleted)  -- 复合索引,优化班级就业统计

外键:

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(可直接执行)

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 规划)

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):

-- 查询学生时关联字典获取可读名称
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 年
  • 或主动标记为"已归档"状态