/cn-tutor-prep-s5-ict-databases-sql/
/cn-tutor-prep-s5-ict-databases-sql/
简体版
2
一般查询: info@TutorZone.com.hk
办公时间: 星期一至六 - 上午 9 时至下午 6 时
WhatsApp 星期一至日 - 24 小时
人手接听: +852 6828 1809
实时客服: +852 9061 3106

DSE ICT|关联式数据库与 SQL 备课指引(导师用)|主键外键、正规化与查询效率

DSE ICT|关联式数据库与 SQL 备课指引(导师用)|主键外键、正规化与查询效率

  • 2026-11-02

学生识抄 SELECT * FROM Student,但讲不出为何要拆表、为何要开索引。这一堂用三张表和两条成本算式,把“数据库设计”变成可以批分的判断。

本堂目标 学生能够:① 用主键与外键讲出两张表如何连接,并用 1,200 名学生中 120 人未选课(10.0%)示范孤儿记录的检查方法;② 把一张夹杂学生姓名与课程名称的选课表拆成 1NF/2NF/3NF 三张表,讲出更新异常、插入异常与删除异常各自如何消失;③ 比较全表扫描 1,200 次比较与索引 11 次,讲出查询快约 109 倍,同时讲出索引在写入与空间上的代价。

01 先备知识(开课前 3 分钟快检)

以下任何一项未过关,本堂就会卡住,先补该项:

技能 快检题 过关标准
资料表 一张表有字段与记录 每行一笔记录,每栏只放一种资料
对数 二的几次方接近 1,200 约 10.2,向上取整要 11 次比较
百分比 120 占 1,200 几成 10%

02 课堂流程(60 分钟)

时间 环节 导师做什么 学生做什么
0–10 分 一张乱表 学生姓名、课程、导师全塞在一张表 指出三个重复位
10–22 分 主键与外键 独一无二 vs 指回另一张表 算出 120 人未选课
22–34 分 正规化 1NF、2NF、3NF 逐步拆表 拆成三张表
34–44 分 SQL 查询 WHERE、GROUP BY、HAVING、JOIN 写出三条查询
44–54 分 索引与成本 全表扫描对比 B 树索引 算出快 109 倍
54–60 分 离场检查 三题即场批 三题全对

03 讲解脚本(照着说就可以)

第一幕:两张表靠一条键接上

学生表 Students 有 1,200 行,选课表 Enrolments 有 4,860 行,平均每人 4,860 ÷ 1,200 = 4.05 科。
主键是每行独一无二的识别,例如 student_id;外键是写在另一张表、指回主键的字段,例如 Enrolments.student_id。
外键管的是参照完整性:Enrolments 出现的每个 student_id,Students 必须有这一行,否则叫孤儿记录。检查很机械:SELECT COUNT(DISTINCT student_id) FROM Enrolments 得 1,080,1,200 − 1,080 = 120 人未选课,占 10.0%。
删除规则要一齐讲:ON DELETE CASCADE 会连选课一齐删,ON DELETE RESTRICT 会阻止删除。答题要写出选哪一个和理由,而不是只写“外键”。
合成主键(student_id + course_id)也是一条考点:它保证同一人同一科不会重复报名。

要学生讲:为何 student_id 可以在 Enrolments 重复出现,但不可以重复出现在 Students(一个是外键,一个是主键)。

第二幕:拆表不是洁癖,是防止三种异常

原本一张表同时放 student_id、student_name、course_id、course_name、teacher_name。问题有三个:更新异常(改了课程名称要改 4,860 行,漏一行就前后不一致)、插入异常(新课程未有人报名就无法记录)、删除异常(删走最后一个学生,连课程资料一齐消失)。
拆成 Students(student_id、name)、Courses(course_id、course_name、teacher)、Enrolments(student_id、course_id、grade)之后:1NF 每格只有一个值;2NF 非主键字段要依赖整个合成主键,所以 grade 留在 Enrolments,course_name 搬去 Courses;3NF 去掉传递依赖,teacher 只依赖 course_id 就留在 Courses。
同一个课程资料由 4,860 次重复变成 40 行(4,860 ÷ 121.5),更新一次就一致。
代价是查询要 JOIN 两三张表,这就是“拆表换一致性”。

要学生讲:拆表之后查询变慢,为何仍然值得(一致性与异常消失换少量 JOIN 成本)。

第三幕:索引是拿写入换读取

没有索引时,找一个 student_id 要逐行比对,最坏情况 1,200 次比较。有 B 树索引就等于每次砍一半,比较次数约 log₂1,200 ≈ 10.2,向上取整 11 次,快约 1,200 ÷ 11 = 109 倍。
但索引不是免费:每个索引要多占空间,每次 INSERT/UPDATE/DELETE 都要同时改索引,所以写入多的表不宜乱开。
几时值得开:常在 WHERE、JOIN 或 ORDER BY 出现的字段;几时不值得:只有几十行的小表、选择性极低(例如性别只有两个值)的字段。
SQL 题要按口诀写:SELECT 拣栏、FROM 拣表、WHERE 筛行、GROUP BY 分组、HAVING 筛组、ORDER BY 排序。HAVING 与 WHERE 的分别几乎每年都考:WHERE 在分组前筛行,HAVING 在分组后筛组。

要学生讲:为何在性别字段开索引帮不到多少(选择性低,仍要读大量行)。

04 必教题型与步骤

题型 例子 步骤 答案
设计 由需求画出三张表与键 找主体 → 定主键 → 加外键 → 检查异常 三表+两条外键
SQL 写查询 SELECT → FROM → JOIN → WHERE → GROUP BY → HAVING 语法齐全
计算 索引比较次数 ceil(log2(行数)) 11 次
解释 正规化消除哪种异常 逐层讲 1NF、2NF、3NF 每层一个例子
合理性检查(一定要教):主键必须独一无二且不可为空,外键可以重复。
索引比较次数用 log₂,不是除以 2 的次数直接相加。
1,200 ÷ 11 = 109.1,不是 109 万倍;单位是“倍”不是“百分比”。
HAVING 不可以放在 GROUP BY 之前。
拆表后 JOIN 的条件要写在 ON 或 WHERE,漏写会变成笛卡儿积(1,200 × 4,860 行)。

05 独立练习三题

题目 答案 想观察什么
1,200 名学生、4,860 条选课的平均科数 4.05 科 4,860 ÷ 1,200
1,080 人选课,几多人未选 120 人(10.0%) 1,200 − 1,080
1,200 行表的索引最坏比较次数 11 次 ceil(log2 1,200)

06 学生常见错误与纠正句

错误 学生通常这样写 导师这样说
把外键当主键 答“student_id 在 Enrolments 是主键” “Enrolments 的主键系 student_id 加 course_id,单一条 student_id 只系外键。”
正规化只写“减少重复” 答“3NF 就系不重复” “要讲消除边种异常:更新、插入、删除,各举一个。”
索引一定好 答“所有字段都开索引就最快” “写入要维护索引,选择性低的字段开了帮助有限。”
JOIN 漏写条件 答“SELECT * FROM A, B” “漏 ON 就变成 1,200 乘 4,860,答题会被扣分。”

07 家课建议(直接指到练习卷题号)

08 离场检查(最后 5 分钟)

题目 答案 判定
未选课人数与比例 120 人/10.0% 三题全对=可进正规化
索引比较次数 11 次 错一题=下堂前重讲对数
HAVING 与 WHERE 分别 分组后 vs 分组前 错两题以上=回到第三幕

09 导师常问

要背 SQL 全部语法吗?

不必。SELECT、WHERE、GROUP BY、HAVING、JOIN、ORDER BY 六个够应付大部分题目。

一定要拆到 3NF 吗?

考试答 3NF;实际系统有时为速度刻意反正规化,要讲明代价。

索引同主键有什么关系?

主键通常自动有索引,但额外索引是独立决定,要按查询模式开。

立即免费找导师导师登记 →

本页为 TutorZone 导师备课指引,内容由 TutorZone 团队编写;题目与流程为原创,并非任何学校或出版社的教材。

招募导师及兴趣班教练|学术、乐器、体育、艺术、STEM,免费登记,招生与配对交给平台。 了解详情 →