/tutor-prep-s5-ict-databases-sql/
/tutor-prep-s5-ict-databases-sql/
一般查詢: 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,免費登記,招生與配對交給平台。 了解詳情 →