
1) 【一句话结论】采用关系型数据库设计核心数据模型(学生、课程、成绩三表),通过时间范围查询用B+树索引、教师查询用联合索引,结合按时间分表和Redis缓存优化性能。
2) 【原理/概念讲解】
老师会先讲数据模型设计:核心是“三表结构”——学生表(存储学号、姓名、班级等)、课程表(存储课程ID、课程名、教师ID、开课时间等)、成绩表(存储学号、课程ID、成绩、考试日期等),学习行为数据作为日志表(存储行为ID、学号、课程ID、行为类型、时间戳)单独存储,支持后续分析。
接着讲索引优化:B+树索引适合范围查询(如按时间范围查成绩,因为B+树能高效定位连续时间区间),哈希索引适合精确匹配(如按教师ID查课程表,哈希索引能快速定位唯一键)。
再讲分表分库:按时间维度(如学年、学期)拆分表(如按学年拆分成绩表),将单表数据分散到多个小表,减少单表查询压力,提升范围查询效率。
最后讲缓存:对高频查询结果(如教师课程表)缓存到Redis,降低数据库访问频率,提升响应速度。
3) 【对比与适用场景】
| 策略 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| 按时间分表 | 根据时间维度(如学年、学期)拆分表 | 单表数据量小,范围查询快 | 按时间范围查询(如近一年成绩) | 需维护时间维度索引,新增数据需选对应表 |
| 按教师分表 | 根据教师ID拆分课程表 | 教师专属课程查询快 | 按教师查询课程表(如张老师课程) | 跨教师查询需多表连接,数据分散 |
4) 【示例】
表结构:
学生表(student):id(主键)、name、class_id
课程表(course):id(主键)、course_name、teacher_id(外键)、start_time
成绩表(grade):id(主键)、student_id(外键)、course_id(外键)、score、exam_date
学习行为表(behavior):id(主键)、student_id(外键)、course_id(外键)、behavior_type、timestamp
查询优化示例:
按时间范围查成绩(近三个月):
SELECT * FROM grade WHERE student_id = ? AND exam_date BETWEEN ? AND ? ORDER BY exam_date DESC;
优化:在exam_date字段建B+树索引,覆盖查询(若字段足够)。
按教师查课程表:
SELECT course_name, start_time FROM course WHERE teacher_id = ?;
优化:在teacher_id字段建联合索引(teacher_id, course_name),提升精确匹配和排序效率。
5) 【面试口播版答案】
面试官您好,针对这个问题,我会从数据模型设计、索引优化、分表分库和缓存四个方面来设计数据库方案。首先,核心数据模型会设计三张表:学生表(存储学生基本信息)、课程表(存储课程和教师关联)、成绩表(存储学生成绩,关联学生和课程)。对于学习行为数据,作为日志表单独存储,支持后续分析。然后,查询性能优化方面,针对“按时间范围查询成绩”的需求,会在成绩表的考试日期字段建立B+树索引,因为B+树适合范围查询,能快速定位时间范围内的记录;针对“按教师查询课程表”的需求,会在课程表的教师ID字段建立联合索引(教师ID+课程名),提升精确匹配和排序效率。另外,考虑到数据量增长,会采用按时间维度分表(比如按学年拆分成绩表),将单表数据分散到多个小表,减少单表查询压力。对于高频查询(如教师课程表),会引入Redis缓存,将查询结果缓存到内存,降低数据库访问频率。这样设计既能满足当前查询需求,又能应对未来数据增长。
6) 【追问清单】
7) 【常见坑/雷区】