本文重構原零散筆記為結構化知識圖譜,涵蓋規範化、連接查詢、事務、常用語句四大核心模組,適合快速複習與查漏補缺。
《Head First SQL》
├── 1. 規範化
│ ├── 1.1 約束
│ ├── 1.2 原子性
│ ├── 1.3 第一范式 (1NF)
│ ├── 1.4 數據模式 (Schema)
│ │ ├── 一對多
│ │ ├── 多對多
│ │ └── 依賴 (函數依賴 T.x → T.y)
│ └── 1.5 更高范式 (2NF/3NF/BCNF)
├── 2. 連接查詢
│ ├── 2.1 交叉連接 (CROSS JOIN / 笛卡爾積)
│ ├── 2.2 內連接 (INNER JOIN)
│ ├── 2.3 子查詢
│ │ ├── 非相關子查詢 (獨立執行)
│ │ └── 相關子查詢 (引用外層)
│ ├── 2.4 外連接 (LEFT/RIGHT JOIN)
│ ├── 2.5 自連接 (Self JOIN)
│ └── 2.6 集合操作 (UNION/INTERSECT/EXCEPT)
├── 3. 事務
│ ├── 3.1 ACID 特性
│ │ ├── 原子性
│ │ ├── 一致性
│ │ ├── 隔離性
│ │ └── 持久性
│ └── 3.2 事務管理
│ ├── BEGIN/START TRANSACTION
│ ├── COMMIT
│ ├── ROLLBACK
│ └── SAVEPOINT
└── 4. 常用語句與注意事項
├── DDL (CREATE/ALTER/DROP)
├── DML (INSERT/UPDATE/DELETE)
├── DQL (SELECT/JOIN/WHERE/GROUP BY/HAVING/ORDER BY/LIMIT)
├── DCL (GRANT/REVOKE)
└── 索引/鎖/隔離級別/優化提示
ingredients: 'flour,milk,egg' 或 student1, student2 多列同義。T.x → T.y 表示 y 由 x 唯一決定。完全函數依賴、部分依賴、傳遞依賴是 2NF/3NF 判斷依據。| 類型 | 結果集 | 典型場景 | 關鍵語法 |
|---|---|---|---|
| CROSS JOIN | m × n 行(笛卡爾積) | 極少用,生成測試數據 | 無 ON 條件 |
| INNER JOIN | 雙方匹配行 | 最常用,如訂單+用戶 | ON 條件或 WHERE |
| LEFT JOIN | 左表全保留,右表無匹配為 NULL | 主表帶從表(用戶+訂單,含無訂單用戶) | ON 條件(勿移至 WHERE) |
| RIGHT JOIN | 右表全保留 | 少用,可改 LEFT JOIN 交換表順序 | 同上 |
| NATURAL JOIN | 同名列自動匹配 | 危險:列名變更導致語義變 | 無 ON |
| SELF JOIN | 表自我關聯 | 層級結構(員工-經理)、鏈表 | 別名區分 t1, t2 |
| 特性 | 含義 | InnoDB 實現 |
|---|---|---|
| 原子性 | 全做或全不做 | Undo Log 回滾 |
| 一致性 | 約束/觸發器保證數據正確 | 外鍵、檢查約束、應用層邏輯 |
| 隔離性 | 並發事務互不干擾 | MVCC + 鎖(行鎖、間隙鎖、Next-Key Lock) |
| 持久性 | 提交後永久生效 | Redo Log (WAL) + 雙重寫緩衝區 |
四大隔離級別(由低到高,鎖/一致性越強):
-- 建表
CREATE TABLE t (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL DEFAULT '',
status TINYINT NOT NULL DEFAULT 1,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 條件查詢分頁
SELECT * FROM t WHERE status=1 ORDER BY created_at DESC LIMIT 0,20;
-- 聚合統計
SELECT status, COUNT(*) AS cnt FROM t GROUP BY status HAVING cnt > 100;
-- 事務範例
START TRANSACTION;
UPDATE account SET balance = balance - 100 WHERE id = 1;
UPDATE account SET balance = balance + 100 WHERE id = 2;
COMMIT; -- 或 ROLLBACK;
NOT IN 子查詢結果含 NULL 會導致空結果集,改用 NOT EXISTS。COUNT(*) vs COUNT(col):前者含 NULL 行,後者不含。WHERE varchar_col = 123 應為 WHERE varchar_col = '123'。《Head First SQL》以視覺化、對話式風格降低 SQL 學習門檻,建議配合實操練習,將知識圖譜內化為肌肉記憶。