
1) 【一句话结论】
核心是构建“课程-章节-课时-知识点”层级模型,通过多表关联实现多校区、多教师、多版本管理,结合乐观锁+事件驱动保证数据实时一致性,并利用索引、分库分表、缓存优化查询性能。
2) 【原理/概念讲解】
Course表中增加campus_id字段,明确不同校区课程版本差异,类似“给每个课程贴上校区标签,确保不同校区看到的是对应版本”。Version表存储版本信息(字段version_num),教师修改课时内容时生成新版本记录,历史版本保留以支持追溯,类似“版本就像课程内容的“快照”,每次修改都生成新快照,方便回溯”。Teacher_Course中间表,字段role区分主讲/助教),支持多校区教师管理多课程,类似“教师和课程的关系是多对多,比如一位教师可以主讲多个课程,同时多个教师可以参与一个课程”。Version表(记录版本号、时间),再发布事件(如“课程更新”),学生端订阅该事件后实时拉取最新数据(事件驱动实现最终一致性,延迟控制在秒级),类似“教师修改后,通过消息队列通知所有学生端,学生端收到后更新本地数据,保证实时性”。version_num分页)使用索引;数据量大时按course_id范围分片(如course_id % 100),避免热点数据集中;缓存热点数据(如热门课程)到Redis提升查询速度,类似“给常用查询建索引,分库分表避免单库压力,缓存热点数据减少数据库访问”。3) 【对比与适用场景】
| 设计方案 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| 乐观锁(版本号) | 通过版本号校验冲突,冲突时回滚 | 低并发,冲突时回滚 | 低并发场景 | 需要频繁回滚处理 |
| 事件驱动 | 发布-订阅模式,教师修改后发布事件,学生端订阅 | 高并发,实时更新 | 高并发实时更新需求 | 需要消息队列支撑 |
| 范围分片 | 按主键范围(如course_id % N)分片 | 扩展性好,负载均衡 | 数据量增长,避免单库瓶颈 | 需要热点数据分布均匀 |
| 哈希分片 | 按哈希值(如course_id % N)分片 | 避免热点数据集中 | 热点数据较多 | 分片键选择不当可能导致数据倾斜 |
4) 【示例】
-- 课程表(含多校区)
CREATE TABLE Course (
course_id INT PRIMARY KEY,
name VARCHAR(100),
campus_id INT, -- 多校区标识
version INT DEFAULT 1,
create_time TIMESTAMP
);
-- 章节-课时-知识点层级
CREATE TABLE Chapter (
chapter_id INT PRIMARY KEY,
course_id INT,
order INT,
name VARCHAR(50),
FOREIGN KEY (course_id) REFERENCES Course(course_id)
);
CREATE TABLE Lesson (
lesson_id INT PRIMARY KEY,
chapter_id INT,
knowledge_point_id INT,
teacher_id INT,
content TEXT,
version_num INT, -- 课时版本号
create_time TIMESTAMP,
FOREIGN KEY (chapter_id) REFERENCES Chapter(chapter_id)
);
CREATE TABLE KnowledgePoint (
knowledge_point_id INT PRIMARY KEY,
name VARCHAR(100),
description TEXT
);
-- 教师表(含校区)
CREATE TABLE Teacher (
teacher_id INT PRIMARY KEY,
name VARCHAR(50),
campus_id INT
);
-- 教师与课程多对多关联
CREATE TABLE Teacher_Course (
teacher_id INT,
course_id INT,
role ENUM('主讲','助教'),
PRIMARY KEY (teacher_id, course_id),
FOREIGN KEY (teacher_id) REFERENCES Teacher(teacher_id),
FOREIGN KEY (course_id) REFERENCES Course(course_id)
);
-- 版本历史表
CREATE TABLE Version (
version_id INT PRIMARY KEY,
course_id INT,
version_num INT,
create_time TIMESTAMP,
description VARCHAR(200),
FOREIGN KEY (course_id) REFERENCES Course(course_id)
);
POST /api/lesson/update
{
"course_id": 101,
"lesson_id": 201,
"content": "更新后的课时内容",
"version_num": 2
}
接口逻辑:
lesson.version_num)是否与请求中的version_num一致,不一致则返回冲突提示;Lesson表(content更新,version_num递增);Version表(course_id=101, version_num=2, description="教师修改内容");CourseUpdated(101,2)”到Kafka;5) 【面试口播版答案】
“面试官您好,针对多校区、多教师、多版本课程的需求,我设计的数据库模型核心是围绕‘课程-章节-课时-知识点’的层级结构,通过多表关联实现复杂关系。具体来说,课程表存储基础信息,章节、课时、知识点表按层级关联;教师与课程是多对多,用中间表关联。为了支持多版本,每个课程有版本号,修改时生成新版本记录到Version表,通过事件驱动(教师修改后发布事件,学生端订阅)保证实时更新。多校区方面,课程表增加campus_id字段明确校区归属。性能优化方面,对课程搜索(倒排索引)和版本历史查询(按版本号分页)使用索引,数据量大时按课程ID范围分片,缓存热点数据到Redis,确保查询性能。”
6) 【追问清单】
Version表按version_num排序,分页查询(如SELECT * FROM Version WHERE course_id=xxx ORDER BY version_num DESC LIMIT 10,20)。course_id % 100),或按版本号分片,避免热点数据集中。7) 【常见坑/雷区】
campus_id字段或Course_Campus表,导致多校区课程版本差异无法管理。