ER 建模與正規化:從需求語句到穩定資料表
本頁為依教材與考古題整理的原創摘要;考古題答案經技術覆核,但不是官方答案。
第一次接觸也沒關係
這堂先懂這些詞
先記住白話意思,不必急著背英文。看到正文時,再把正式名稱接回來。
關係基數
也會看到:cardinality、one-to-many、many-to-many、1:N、M:N描述兩類實體之間能互相對應幾筆資料。
- 生活例子:
- 一位會員可有多張訂單,是一對多關係。
- 別搞混:
- cardinality 在資料建模與查詢最佳化中可能有不同語境,要看上下文。
函數相依
也會看到:functional dependency、partial dependency、transitive dependency若欄位 X 的值能唯一決定欄位 Y,就寫成 X 決定 Y,並用來判斷表格冗餘。
- 生活例子:
- 知道學號就能查到學生姓名,表示學號決定姓名。
- 別搞混:
- 資料剛好沒有重複不等於存在函數相依;相依來自業務規則。
資料庫正規化
也會看到:normalization、1NF、2NF、3NF、BCNF依資料相依性拆表,減少重複與新增、修改、刪除異常。
- 生活例子:
- 把客戶地址從每張訂單抽成會員資料,避免改地址要改很多次。
- 別搞混:
- 正規化不是表越多越好,分析效能需求可能採有理由的反正規化。
主鍵與外鍵
也會看到:primary key、foreign key、PK、FK、主鍵、外來鍵主鍵唯一識別本表資料,外鍵則指向另一表的主鍵來建立關係。
- 生活例子:
- 身分證字號辨認一個人,訂單上的會員編號則連回會員資料。
- 別搞混:
- 外鍵不一定唯一;它的重點是參照完整性,不是替資料排序。
先用 entity、attribute、relationship、cardinality 建立概念模型,再以 functional dependency、1NF、2NF、3NF 分解冗餘與更新異常。
先抓住這幾件事
- 辨識 entity、attribute、relationship 與 cardinality
- 把 ER 關係映射到 relational schema
- 由 functional dependency 判斷 partial 與 transitive dependency
- 說明 1NF、2NF、3NF 的目標及 lossless 分解的重要性
先想像這個場景
社團報名系統重建
社團原本把社員、活動、幹部與報名紀錄塞進同一張試算表;活動改名要改數十格,刪掉最後一位報名者竟連活動資訊也消失。
先別急著往下看,花十秒想一想:
若一位學生可報多場活動,而每場活動也有多人參加,能否只在 Student 放一個 activity_id 就完整表示?
把故事換成電腦語言
| 生活中的角色 | 對應到 | 技術概念 |
|---|---|---|
| 學生、活動是可獨立辨識的名詞 | Entities | |
| 學生報名活動這件事 | Relationship | |
| 一位學生多場活動、每場活動多人 | Many-to-many cardinality | |
| 學號固定決定姓名 | Functional dependency | |
| 拆出 Student、Activity、Registration | Normalization 與 junction relation |
題目出現這些字,先想到
- 看到 diamond:傳統 ER notation 表 relationship;attribute 通常是 oval。
- 看到 many-to-many 且 relationship 有屬性:建立 junction relation。
- 看到 2NF:找 composite key 的 partial dependency;單一 key 不會有此問題。
- 看到 3NF:找 non-key 到 non-key 的 transitive dependency,不要答成增加重複資料。
1.ER model 是需求與資料表之間的概念橋梁
Entity 是可獨立辨識的事物,attribute 描述其性質,relationship 表示 entities 間的關聯。傳統 ER 圖常用 rectangle 表 entity、oval 表 attribute、diamond 表 relationship;符號只是表達工具,真正要讀的是語意。
- Schema 描述資料庫邏輯結構
- Key attribute 唯一辨識 entity
- Weak entity 依賴 owner entity
- Cardinality 描述 one-to-one、one-to-many、many-to-many
2.Cardinality 決定 foreign key 或關聯表位置
一對多通常把一方的 primary key 放到多方作 foreign key;多對多需建立 junction relation,至少包含兩端 keys。若 relationship 自己有屬性,例如修課成績,應放在 junction relation。
- Foreign key 維護 referential integrity
- Many-to-many 不能只在某一端放單一 foreign key
- Optional participation 要考慮 null 或獨立 relation
- Mapping 前先確認每一筆 relationship 的身份
3.Functional dependency 是正規化的判斷語言
X→Y 表示兩筆 tuple 若 X 相同,Y 必須相同。Candidate key 能決定全部 attributes。Partial dependency 是 non-key attribute 只依賴 composite key 的一部分;transitive dependency 是 key 經另一 non-key attribute 間接決定第三者。
- FD 來自資料語意,不只看目前樣本巧合
- Determinant 在箭頭左側
- Superkey 可包含多餘 attributes
- 同一 relation 可能有多個 candidate keys
4.1NF 到 3NF 逐步移除不同異常來源
1NF 要求每個 attribute value 在該 relational design 中為 atomic,不含 repeating group。2NF 在 1NF 上移除 non-prime attribute 對 candidate key 的 partial dependency。正式 3NF 判斷每個 non-trivial FD X→A:X 必須是 superkey,或 A 是 prime attribute;常見的『移除 non-key 間 transitive dependency』是便於入門的情境化口訣。
- 單一欄位值是 atomic 是 1NF 核心
- 單一屬性 candidate key 不會有 partial dependency
- 3NF 不是表越少越好
- 分解要考慮 lossless join 與 dependency preservation
一起拆題目
範例 1:學生可選多門課,課程也有多名學生,且每次選課有 grade。如何映射?
- 建立 Student(student_id, ...)
- 建立 Course(course_id, ...)
- many-to-many 另建 Enrollment(student_id, course_id, grade)
- 兩個 IDs 組成 key 並分別作 foreign keys
所以答案是:以 Enrollment junction relation 表示選課 relationship,grade 屬於該 relationship。
範例 2:Enrollment(student_id, course_id, student_name, course_title, grade),key=(student_id,course_id)。指出 partial dependencies。
- student_id→student_name,只依賴 composite key 一部分
- course_id→course_title,也只依賴一部分
- grade 依賴完整選課組合
所以答案是:拆成 Student、Course、Enrollment,可移除 student_name 與 course_title 的 partial dependencies。
這裡最容易選錯
- 把 diamond 說成 attribute
- 把 many-to-many 直接塞成單一 foreign key
- 從幾筆樣本猜 FD,而忽略業務規則
- 把 primary key 要求誤當成 1NF 唯一定義
- 認為正規化就是表越多越好
- 分解後未檢查 lossless join
換你快速判斷
先在心中作答,再展開答案。答不出來時,回頭找本課的對照關係。
1傳統 ER diagram 中 rectangle、oval、diamond 各代表什麼?
Rectangle 表 entity、oval 表 attribute、diamond 表 relationship。
Weak entity 常用 double rectangle;符號需連同 cardinality 與 participation 語意判讀。
2Many-to-many relationship 映射到 relational schema 時通常怎麼做?
建立 junction relation,放入兩端的 keys 作 foreign keys,並承載 relationship 自己的 attributes。
例如 Enrollment(student_id, course_id, grade),grade 屬於選課關係。
31NF、2NF、3NF 分別主要排除什麼?
1NF 要求 atomic values;2NF 排除 non-prime attribute 對 candidate key 的 partial dependency;3NF 要求每個 non-trivial FD X→A 中,X 是 superkey 或 A 是 prime attribute。
『排除 non-key 間 transitive dependency』是常見入門口訣;正式判斷仍要考慮所有 candidate keys 與 prime attributes。正規化不是機械地增加 table 數量。
4Functional dependency X→Y 的精確含義是什麼?
任何兩筆 tuples 若 X 值相同,其 Y 值也必須相同;X 決定 Y。
FD 源自業務語意,不能只因目前 sample 恰好相同就斷定成立。
最後用考古題驗證
本課連結的題目都已通過可重現的技術覆核,可逐題練習與判分。
開始本課考古題練習參考來源
- Computer Science: An Overview, 13th Edition — J. Glenn Brookshear
- 資料庫課程 — 陳士杰(杰哥數位教室)