學生背得出一句 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 團隊編寫;題目與流程為原創,並非任何學校或出版社的教材。