Teaching Database · 四层课堂设计

讲好数据库
靠一个真的库

数据库课最容易上成「SQL 语法背诵 + 范式定义默写」。但只要整学期只瞄准一个真实在用的库—— 你平台上跑着的那个——学生的每一条 SELECT 都能看见结果,每一次建索引都能听见速度变化。

理念 · 建一个真的库 结构 · 读 / 写 / 守 课堂 · 让执行计划说话 手册 · 三张纸带回家
classroom@mysql · 只读副本 EXPLAIN 现场
studentsid PKnamemajor
enrollmentsstudent_id FKcourse_idterm / score
coursesid PKtitleteacher
SELECT s.name, COUNT(e.course_id) AS 选课数,
       ROUND(AVG(e.score),1) AS 均分
FROM students s
JOIN enrollments e ON s.id = e.student_id
WHERE e.term = '2026-秋'
GROUP BY s.name
ORDER BY 选课数 DESC
LIMIT 5;
access_typeALL · 全表扫描 rows_examined1,204,880 extraUsing temporary; Using filesort
1.84 s
name选课数均分
林可为992.3
赵一鸣888.7
周小满886.1
陈迟785.4

课堂用法:同一句 SQL,点一下建索引,1.84 秒变 0.02 秒——数据库课最该让学生亲眼看到的一幕。

01 / 理念层IDEA

把「讲 SQL 语法」换成「建一个真的库」

数据库是一门「说了不算、跑出来才算」的课。四条规矩,直接决定学生是在背语法还是在做工程。

RULE 01

一库到底,不换示例库

整学期只用你平台上那批真实表(脱敏副本):学生、课程、选课、采集事件。第 1 周的 SELECT 和第 15 周的分库分表,查的是同一批数据,认知才连得起来。

RULE 02

每节课产出一条可复现的 SQL

下课时学生手里必须有一个能跑出结果的 .sql 文件,或者一张 ER 图、一份执行计划截图。不是笔记,是可被再次执行的产物。

RULE 03

报错与慢查询是教材

现场写出外键冲突、唯一键重复、死锁,全班一起读报错。把 EXPLAIN 当 X 光片讲——数据库不是黑盒,是账本 + 仓库,要能被看穿。

RULE 04

最后一周,学生改的索引真上线

给平台后端做一次真实的表结构评审与索引优化,在大屏上量出前后差。「这条索引是我加的」,比任何课后题都有说服力。

「数据库课不该教学生写 SQL,该教学生为自己的数据负责。」 —— 一句话版本:把课堂产出物,从「查询语句」换成「一个有人用、有人维护的库」。
02 / 结构层TRACKS

三条主线:读、写、守

会查(读)、会设计(写)、能在出问题时救回来(守)。多数课程只讲前两条,第三条才是学生进公司后第一周就要用的。

查询线 · 读

READ · 从数据里问出结论
  1. 单表 SELECT / WHERE / ORDER
  2. JOIN:内、左、自连接
  3. 聚合 + GROUP BY + HAVING
  4. 子查询 / 窗口函数
  5. 用真实业务问题收口

每一问都落在学生自己身上:我这学期选了几门课、班上谁缺勤最多、哪门课均分最低。

设计线 · 写

WRITE · 从需求到表结构
  1. 需求 → 实体与关系 → ER 图
  2. 范式:为什么这样拆
  3. DDL:主键、外键、约束
  4. 索引与查询的匹配
  5. 反范式的取舍

范式不先讲定义,而是从「一份 Excel 存了所有东西」的痛点倒推出来。

杀手锏

运维线 · 守

OPERATE · 出事时救得回来
  1. 备份与恢复(真删一次、真恢复一次)
  2. 账号权限与最小授权
  3. 慢查询定位 + EXPLAIN 调优
  4. 事务、隔离级别、锁与死锁
  5. 主从 / 读写分离的取舍

期中给平台后端做一次表结构评审与索引优化,把大屏上的慢查询从 2 秒打到 20 毫秒——学生加的索引真上线。

Python 课的采集器写进 crawl_events,数据库课负责为它设计表结构与索引,大屏负责把它显示出来—— 两门课互为上下游,学生的代码从「交作业」变成「跑在系统里的一环」。
03 / 课堂层MOVES

讲得好的六个动作

数据库课最怕「老师敲一句、学生抄一句」。这六个动作都指向同一件事:让结果自己说话。

MOVE 01

先给结果,再要 SQL

先甩出一张结果集截图:「这就是我要的答案,你把它写出来。」逆向比正向好学,学生一上来就在解决问题,而不是记语法。

现场版 · 先亮「这学期谁选课最多」的结果表,倒逼学生自己写出 GROUP BY。

MOVE 02

现场炸一次笛卡尔积

两张一万行的表不加连接条件,看着行数从 1 万变 1 亿、磁盘告警。这一炸,JOIN 条件这辈子不会忘。

现场版 · 行数飙到 1 亿、风扇拉满的那 3 秒——比讲十分钟笛卡尔积定义都管用。

MOVE 03

用「烂库」教设计

先给一个没有主键、全是 VARCHAR、日期存成字符串、索引乱加的库,让学生跑一遍又慢又错;再让他们亲手重建成规范结构。

现场版 · 发一个「学生表里塞了整张课表」的库,日期存成 '2026/9/1号' 这样的文本。

MOVE 04

写完必看 EXPLAIN

每句 SQL 提交前必须点一次执行计划,并能口头解释「为什么慢」。这是从背语法跨到做工程的分水岭。

现场版 · 口头追问:「扫了 120 万行,返回只有 37 行——中间发生了什么?」

MOVE 05

当堂提交,实时排行榜

学生把 SQL 与耗时提交到 class_answers,大屏实时显示「谁的结果对、谁的最快」。你现成的大屏就是数据库课的评测榜。

现场版 · 同一道题全班耗时上墙,最慢与最快差 400 倍——这个差值就是下一节课的引入。

MOVE 06

双会话并发演示

开两个会话同时扣同一件库存,让不可重复读、脏读、死锁在现场发生一次。事务从「背 ACID」变成「我见过」。

现场版 · 两个窗口同时扣最后一件库存,超卖当场发生——再讲 SELECT ... FOR UPDATE。

04 / 避坑层PITFALLS

三个最常见的流失点

数据库课的放弃率通常来自三处:开局的抽象、中段的断裂、末端的不真实。

✕开局就讲 1NF / 2NF / 3NF / BCNF
→
✓先用「一份 Excel 存所有东西」的踩坑引出问题,范式作为「为什么必须这么拆」的答案出现。
✕只教 SELECT,不教数据从哪来、干不干净
→
✓先发一批脏数据:重复、缺值、日期是文本。清洗一遍再查询,学生才知道数据工作有多脏。
✕索引与事务当成背诵考点
→
✓每加一个索引都用 EXPLAIN 和秒表证明它有用;每个隔离级别都在双会话里跑一遍。
✕建表与调优全让 AI 一键生成
→
✓先手绘 ER 图,再让 AI 来挑刺——学生必须写出「AI 哪一条说错了」才算通过。评 AI 比写 SQL 更接近工程师。
05 / 落地RHYTHM

一学期的节奏

从「只读副本上跑查询」开始,以「答辩你的表为什么这么设计」结束。

第 1–2 周
在只读副本上跑单表查询,用平台真实数据得出 3 个有意思的结论(不改任何数据)
产物 · 3 个真实结论
第 3–4 周
JOIN + 聚合 + 子查询,做出一份班级学习行为报表
产物 · 班级学习行为报表
第 5–6 周
ER 设计 + 范式 + DDL:给一个真实需求建库(课表 / 社团 / 借阅任选)
产物 · 可运行的建库脚本 + ER 图
第 7–8 周
索引与 EXPLAIN:让某条慢查询提速,提交前后耗时对比
产物 · 前后耗时对比卡
期中
给平台后端做表结构评审与索引优化,产出评审意见书(系统线启动)
产物 · 评审意见书(真上线)
第 9–12 周
事务、锁、隔离级别、权限、备份恢复;一次故障演练:真删、真回滚、真恢复
产物 · 故障演练记录
第 13–15 周
每人一个自己设计的小库 + 一份运维手册(备份策略、索引清单、慢查询记录)
产物 · 个人小库 + 运维手册
期末
答辩:「你的表为什么这么设计」——带 ER 图与执行计划上场
产物 · 10 分钟答辩
06 / 手册层PLAYBOOK

「让执行计划说话」的三张纸

一张 EXPLAIN 速读卡、一间慢查询急诊室、一张期末答辩评分表——都能直接印了发。

PAPER 01 · EXPLAIN 速读卡完整版 ↗
type什么时候出现它在干什么课堂上的一句话
const主键 / 唯一键等值查询一次定位,只摸一行「拿身份证查人,一翻就中」
ref普通索引等值查询按索引扫一小段「按学号点一个班,一页名册」
range索引上的范围查询扫一段区间「查 60–80 分,翻一段书页」
index覆盖索引扫描顺序扫整棵索引树「比全表快,但仍然在扫」
ALL没有可用索引一行一行全摸「报警。第一反应:索引呢?」

配套口令:先看 type,再看 rows,最后看 Extra。rows_examined 与返回行数差得越远,优化空间越大——120 万行里只取 37 行,就是下面这间急诊室。

PAPER 02 · 慢查询急诊室完整版 ↗
triage.sql · 首页报表 1.84 s 选对索引
SELECT s.name, e.score
FROM students s
JOIN enrollments e ON s.id = e.student_id
WHERE e.term = '2026-秋'
  AND e.score < 60
ORDER BY e.score;
access_type— 待选择 — rows_examined— extra—

三个候选,只有一个建对了地方。选一个,让执行计划宣判。

出题点就两个:最左前缀、等值列在前,范围列在后。选错一次,比讲三遍记得牢。

PAPER 03 · 期末答辩评分表完整版 ↗
维度权重必须出示的证据评委的当场追问
ER 与范式取舍30ER 图 + 一处「故意反范式」的书面说明「这条冗余,什么时候会反过来咬你?」
索引论证20每条关键索引的前后耗时对比(EXPLAIN 截图)「把查询条件换个顺序,它还灵吗?」
故障演练20一次真删 + 真恢复的完整记录「你的备份,自己恢复过几次?」
运维手册20备份策略 / 索引清单 / 慢查询台账「你休假一周,接手的人照着能跑吗?」
讲述与答辩1010 分钟讲清「你的表为什么这么设计」随堂抽一条 SQL:读出它的执行计划。

评分表的潜台词:证据必须在系统里留痕——耗时对比、恢复记录、慢查询台账都来自你现成的大屏与库,不用老师额外造材料。

把任何一周,做成完整教学包

选定一节课,材料可以一次性配齐——全部咬合你现有的库与大屏。

01 / DATA脱敏后的真实教学库 + 建表脚本
02 / BROKEN故意做坏的「烂库」重建文件
03 / DRILL慢查询练习集(含前后耗时答案)
04 / SCREEN当堂提交 + 实时排行榜大屏
选一周试试。