面试场景题——设计低耦合的选课系统数据库表:拆分复杂表是关键。

表关系图

erDiagram Students ||--o{ Student_Course : "选课" Teachers ||--o{ Courses : "授课" Courses ||--o{ Course_Schedule : "时间安排" Courses ||--o{ Student_Course : "被选" Students { INT student_id PK "学生ID" VARCHAR name "姓名" VARCHAR grade "年级" VARCHAR major "专业" } Teachers { INT teacher_id PK "老师ID" VARCHAR name "姓名" VARCHAR department "院系" } Courses { INT course_id PK "课程ID" VARCHAR course_name "课程名称" INT teacher_id FK "老师ID" INT capacity "容量" } Course_Schedule { INT schedule_id PK "时间安排ID" INT course_id FK "课程ID" ENUM day_of_week "星期" VARCHAR time_slot "时间段" } Student_Course { INT id PK "主键" INT student_id FK "学生ID" INT course_id FK "课程ID" ENUM status "状态" }

搞一个大学选课系统的MySQL表结构

开发一个大学选课系统,数据库设计绝对是重头戏,直接决定系统好不好用、跑得快不快,还能不能方便加新功能。今天咱们就聊聊怎么用MySQL搭一个顺手的表结构,满足学生选课、课程管理和时间安排的需求。从需求聊起,一步步设计表,最后还能用Mermaid图秀一下表之间的关系。

先聊聊需求

大学选课系统得搞定这几个核心事儿:

  1. 学生管理:得记下学生的基本信息,比如学号、名字啥的。
  2. 课程管理:课程得管好,名字、老师、能塞多少人,都得有。
  3. 时间安排:课程时间得灵活,一周上几次课或者跨几个时段,都得支持。
  4. 选课管理:记下学生选了啥课,还要能管状态,比如"待审核""已通过""退课"。
  5. 防冲突:选课时得检查时间,别让学生课表撞车。

有了这些需求,咱们就动手设计表结构吧!

表结构怎么搭

1. 学生表 (Students)

先弄个表存学生信息,简单明了。

sql 复制代码
CREATE TABLE Students (
    student_id INT PRIMARY KEY AUTO_INCREMENT, -- 学生ID,自动加1
    name VARCHAR(50) NOT NULL,               -- 名字,必填
    grade VARCHAR(20),                       -- 年级
    major VARCHAR(50)                        -- 专业
);

2. 老师表 (Teachers)

老师也得有自己的表,存基本信息。

sql 复制代码
CREATE TABLE Teachers (
    teacher_id INT PRIMARY KEY AUTO_INCREMENT, -- 老师ID,自动加1
    name VARCHAR(50) NOT NULL,               -- 名字,必填
    department VARCHAR(50)                   -- 院系
);

3. 课程表 (Courses)

课程信息放这儿,名字、老师、容量一个不少。

sql 复制代码
CREATE TABLE Courses (
    course_id INT PRIMARY KEY AUTO_INCREMENT, -- 课程ID,自动加1
    course_name VARCHAR(100) NOT NULL,       -- 课程名字,必填
    teacher_id INT,                          -- 老师ID,连到老师表
    capacity INT,                            -- 能塞多少学生
    FOREIGN KEY (teacher_id) REFERENCES Teachers(teacher_id)
);

4. 课程时间表 (Course_Schedule)

课程时间单独搞个表,灵活排课才方便。

sql 复制代码
CREATE TABLE Course_Schedule (
    schedule_id INT PRIMARY KEY AUTO_INCREMENT, -- 时间ID,自动加1
    course_id INT,                             -- 课程ID,连到课程表
    day_of_week ENUM('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'), -- 星期几
    time_slot VARCHAR(50),                    -- 时间段,比如"上午第一节"或"08:00-09:30"
    FOREIGN KEY (course_id) REFERENCES Courses(course_id)
);

5. 学生选课表 (Student_Course)

学生选课记录放这儿,还能管状态。

sql 复制代码
CREATE TABLE Student_Course (
    id INT PRIMARY KEY AUTO_INCREMENT,        -- ID,自动加1
    student_id INT,                          -- 学生ID,连到学生表
    course_id INT,                           -- 课程ID,连到课程表
    status ENUM('Pending', 'Approved', 'Dropped') DEFAULT 'Pending', -- 状态,默认待审核
    FOREIGN KEY (student_id) REFERENCES Students(student_id),
    FOREIGN KEY (course_id) REFERENCES Courses(course_id),
    UNIQUE KEY (student_id, course_id)       -- 不让学生重复选同一门课
);

设计背后的小九九

为啥这么搞?

  1. 时间单独拎出来 :
    • 课程时间放Course_Schedule表里,不直接写死在课程表里。这样不管是一周上几次课,还是临时调时间,都好办。
  2. 数据整得规范 :
    • 用外键把学生、课程、老师连起来,数据不重复,还不容易出错。
  3. 方便加功能 :
    • Courses里有capacity管人数,Student_Course里有status管审核流程,扩展起来不费劲。
  4. 防时间撞车 :
    • Course_Schedule在手,查学生课表、比对时间冲突,后端一跑就搞定。

试试怎么用

  • 学生选课 :

    sql 复制代码
    INSERT INTO Student_Course (student_id, course_id, status)
    VALUES (1, 101, 'Pending');
  • 查学生课表 :

    sql 复制代码
    SELECT c.course_name, cs.day_of_week, cs.time_slot
    FROM Student_Course sc
    JOIN Courses c ON sc.course_id = c.course_id
    JOIN Course_Schedule cs ON c.course_id = cs.course_id
    WHERE sc.student_id = 1 AND sc.status = 'Approved';

这设计有啥好

  1. 灵活:时间单独管,想怎么调课都行。
  2. 能扩展:人数限制、选课状态啥的都能加。
  3. 防冲突:时间表一查,撞车问题迎刃而解。
  4. 规范:数据不乱七八糟,设计也靠谱。
相关推荐
脚本自动化开发1 天前
折叠双屏MU156LA:写稿修图游戏体验
后端
脚本自动化开发1 天前
AI短剧800集讲规矩,观众忘了是AI
后端
Csvn1 天前
安装、升级与目录结构
后端·nginx
皮皮林5511 天前
万能通用!权限系统就该这么设计
后端
GoAI1 天前
DeepSeek Harness Memory (一)主流记忆插件总结
后端·算法·面试
橙子家1 天前
RESTful 接口:它并非标准或协议,而是一种【架构风格】
后端
小兔子1 天前
dict.get 的默认值每次都会求值,哪怕键本来就在
后端
斯维赤1 天前
限流、熔断、降级,你真的分得清吗?
java·后端·架构
肌肉娃子1 天前
红队攻防测试报告 — wechat-e.cfd
后端
陈随易1 天前
Cmder 停更 17 个月,2.0 支持 Windows Terminal
前端·后端·程序员