学生背得出一句 SELECT,但一问“这个 JOIN 会出几多行”就开始猜。这一堂用行数守住全部概念:300 行对 40 行,配对得 300 行,不配对就得 12000 行。
本堂目标 学生能够:① 指出主键与外键的分工,并讲出为何外键可以重复;② 用 SELECT、WHERE、ORDER BY 写出四种基本查询;③ 用行数判断 JOIN 与笛卡儿积的分别(300 行对 12000 行);④ 讲出索引把逐行扫描(1,000,000 行)换成约 20 次比较的理由。
01 先备知识(开课前 3 分钟快检)
以下任何一项未过关,本堂就会卡住,先补该项:
| 技能 |
快检题 |
过关标准 |
| 集合概念 |
两张表各有 3 行,交叉配对共几多行? |
9 行 |
| 平均值 |
300 除以 40 得几多? |
7.5 |
| 单位换算 |
120,000,000 bytes 等于几多 MB? |
120 MB(以 10 的 6 次方计) |
| 基本英文关键字 |
SELECT 之后写什么? |
要取出的栏名,或 * |
02 课堂流程(60 分钟)
| 时间 |
环节 |
导师做什么 |
学生做什么 |
| 0–10 分 |
表与主键 |
学生表、选课表、主键外键 |
指出哪一栏可以重复 |
| 10–22 分 |
SELECT 与 WHERE |
逐句拆解四个查询 |
自己写出条件句 |
| 22–34 分 |
JOIN 行数 |
300 行与 12000 行的分别 |
计出两种写法的行数 |
| 34–44 分 |
索引 |
1,000,000 行线性扫描对 20 次比较 |
讲出加索引的代价 |
| 44–52 分 |
正规化 |
把一张大表拆成两张 |
自己找重复栏 |
| 52–60 分 |
离场检查 |
三题书面即场批 |
独立完成 |
03 讲解脚本(照着说就可以)
第一幕:主键认人,外键认关系
学生表 40 行,学号是主键,不会重复;选课表 300 行,学号是外键,同一个学号可以出现多次,因为一个学生可以选多科。平均每个学生 7.5 条选课纪录。要学生讲一句:主键认一个人,外键认一段关系,所以外键一定要有重复,重复正是它的功能。
要学生讲出:为何外键一定要允许重复?
第二幕:JOIN 是配对,不是相乘
两张表直接写 FROM students, enrolment 又无条件,就是笛卡儿积,40 乘 300 得 12,000 行,大部分是无意义的组合。写成 JOIN ON students.id = enrolment.sid,只保留配对到的,行数就是 300 行。判断方法很简单:答案行数超过较大的那张表,就一定漏了连接条件。
要学生指出:哪一个写法会出 12000 行,为什么?
第三幕:索引用空间换比较次数
1,000,000 行没有索引时逐行比对,最坏要 1,000,000 次;有索引像查字典,约 20 次比较就到,差 50,000 倍。代价是多占硬盘、每次新增资料都要更新索引。答题要写出“查得快、写得慢、占空间”三件事,只写“快”会被当成背诵。
要学生讲出索引的三个代价与好处。
04 必教题型与步骤
| 题型 |
例子 |
步骤 |
答案 |
| 写查询 |
列出 4A 班全部学生姓名 |
① 选栏 ② 写表 ③ 加条件 ④ 排序 |
SELECT name FROM students WHERE class=’4A’ ORDER BY name |
| 预测行数 |
JOIN 与无条件 FROM |
① 看连接条件 ② 对照较大表 ③ 判断是否笛卡儿积 |
配对 300 行/无条件 12,000 行 |
| 找错处 |
查询漏了 GROUP BY |
① 检查聚合函数 ② 检查非聚合字段 ③ 补 GROUP BY |
COUNT 与班别同用要 GROUP BY class |
| 正规化 |
一张表同时存学生与科目 |
① 找重复 ② 拆表 ③ 用外键连回 |
学生表加选课表,科目名只存一次 |
合理性检查(一定要教):合理性检查:JOIN 的行数永远不会超过两表行数相乘,配对成功时通常等于“多”那一边(本例 300 行);若算到 12,000 行,必然是笛卡儿积。索引的 50,000 倍是理想值,实际受快取与资料分布影响,答题写“大幅减少比较次数”比硬写 50000 倍安全。1,000,000 行乘 120 bytes 得 120 MB,与一般校内习作规模相符。
05 独立练习三题
| 题目 |
答案 |
想观察什么 |
| 两个学生各选 3 科,选课表几多行? |
6 行 |
有无把学生数当成选课数 |
| 40 个学生 300 条选课,平均每人几多条? |
7.5 条 |
有无用 300 除以 40 |
| 无条件 FROM 两表,行数? |
12,000 行 |
有无误以为是 300 行 |
| 一百万行加索引后比较次数约? |
约 20 次 |
有无以为是 100 次 |
06 学生常见错误与纠正句
| 错误 |
学生通常这样写 |
导师这样说 |
| JOIN 漏写连接条件 |
SELECT * FROM students, enrolment; |
“这两张表没有关系,数据库只好全部配对,你叫它做 12000 行的垃圾。” |
| 以为外键不可以重复 |
“学号在选课表只可以出现一次” |
“外键重复才代表一个学生选了几科;不准重复的是主键。” |
| COUNT 不配 GROUP BY |
SELECT class, COUNT(*) FROM students; |
“你想每班一个数,就要 GROUP BY class,否则只会得一个总数。” |
| 以为索引一定好 |
“所有栏都加索引就最快” |
“索引占空间,写入要维护;只加在常用来搜寻的栏。” |
07 家课建议(直接指到练习卷题号)
08 离场检查(最后 5 分钟)
| 题目 |
答案 |
判定 |
| 主键与外键最大分别 |
主键不可重复,外键可以 |
错:讲成“都是唯一的” |
| 40 个学生 300 条选课的 JOIN 行数 |
300 行 |
错:答 12000 |
| 一百万行加索引的比较次数 |
约 20 次 |
错:答 100 或 1000 |
| 索引的代价 |
占空间、写入变慢 |
错:只讲好处 |
09 导师常问
一定要背全部 SQL 语法吗?
校内与 DSE 只考 SELECT、WHERE、ORDER BY、GROUP BY、JOIN 几个,其余看得懂就行。
正规化是否层级越高越好?
要看查询需要;拆得太散每次都要 JOIN,反而慢,答题要讲取舍。
Access 与 SQL 语法一样吗?
概念一样,界面不同;考试写标准 SQL,实习用 Access 的查询设计检视。
立即免费找导师导师登记 →
本页为 TutorZone 导师备课指引,内容由 TutorZone 团队编写;题目与流程为原创,并非任何学校或出版社的教材。