梳理一下 MySQL(或關系型數據庫)中的第一、二、三、四范式,這是數據庫設計中非常重要的規范化理論。
1?? 第一范式 (1NF:First Normal Form)
定義:字段具有原子性,不可再分。
數據表中每一列都必須是不可分割的最小數據單元。
每一行都應該是唯一的(通常通過主鍵來保證)。
? 舉例:
不符合 1NF:
學生表
學號 姓名 聯系方式
1 張三 1380000, 1391111
問題:聯系方式有多個值,違反原子性。
符合 1NF:
學生表
學號 姓名 聯系方式
1 張三 1380000
1 張三 1391111
2?? 第二范式 (2NF:Second Normal Form)
定義:在 1NF 的基礎上,要求每個非主屬性完全依賴于主鍵,不能只依賴主鍵的一部分。
適用于 聯合主鍵 的情況。
消除部分依賴。
? 舉例:
不符合 2NF:
選課表
學號+課程號 (聯合主鍵) 姓名 成績
1+001 張三 95
問題:姓名只依賴學號,而不是依賴于 (學號+課程號) 這個整體主鍵。
符合 2NF(拆表):
學生表
學號 姓名選課表
學號 課程號 成績
3?? 第三范式 (3NF:Third Normal Form)
定義:在 2NF 基礎上,非主屬性不依賴于其他非主屬性(消除傳遞依賴)。
屬性不能依賴于主鍵之外的屬性。
? 舉例:
不符合 3NF:
學生表
學號 姓名 系編號 系名稱
問題:系名稱依賴于系編號,而系編號又依賴學號(學號 → 系編號 → 系名稱,產生傳遞依賴)。
符合 3NF(拆表):
學生表
學號 姓名 系編號系別表
系編號 系名稱
4?? 第四范式 (4NF:Fourth Normal Form)
定義:在 3NF 基礎上,要求多值依賴消除。
一張表中不應包含兩個或多個相互獨立的多對多關系。
? 舉例:
不符合 4NF:
學生表
學號 愛好 擅長課程
1 足球 數學
1 足球 英語
1 籃球 數學
1 籃球 英語
問題:愛好與擅長課程之間是獨立的多值依賴,導致大量冗余。
符合 4NF(拆表):
學生_愛好表
學號 愛好學生_課程表
學號 擅長課程
🔑 總結
1NF:字段不可再分(原子性)
2NF:非主屬性完全依賴主鍵(消除部分依賴)
3NF:非主屬性不依賴于其他非主屬性(消除傳遞依賴)
4NF:不允許一個表里有多個獨立的多值依賴
👉 實際開發中:
3NF 已經能滿足大部分場景;
4NF 更偏學術,業務里一般用到 3NF + 適當的反規范化(為了性能)。
👌 那我幫你整理一個 1NF ~ 4NF 對比表,方便快速理解和記憶:
📊 數據庫范式對比表
范式 | 要求 | 典型問題 | 示例(不符合) | 示例(符合) |
---|---|---|---|---|
第一范式 (1NF) | 字段必須原子化,不可再分 | 字段中有多個值,違反原子性 | 聯系方式: 1380000, 1391111 | 每條記錄一條聯系方式 |
第二范式 (2NF) | 在 1NF 基礎上,非主屬性必須完全依賴主鍵,不能部分依賴 | 聯合主鍵時,非主屬性只依賴其中一部分 | (學號+課程號) → 姓名 | 將姓名拆到“學生表” |
第三范式 (3NF) | 在 2NF 基礎上,非主屬性不能依賴其他非主屬性(消除傳遞依賴) | 非主屬性依賴另一個非主屬性 | 學號 → 系編號 → 系名稱 | 把“系編號-系名稱”拆到“系別表” |
第四范式 (4NF) | 在 3NF 基礎上,消除多值依賴(不能同時描述多個獨立的多對多關系) | 一張表里既存儲“愛好”,又存儲“擅長課程” | 學號 → 愛好 和 學號 → 擅長課程 | 分成“學生_愛好表”和“學生_課程表” |
📌 記憶口訣:
1NF:字段原子化
2NF:消除部分依賴
3NF:消除傳遞依賴
4NF:消除多值依賴
畫一個 范式演進示意圖(從 1NF → 4NF,逐步拆表的過程)這樣更直觀。
畫一個 1NF → 4NF 的演進示意圖,用一個「學生」場景,逐步展示規范化的過程:
📝 范式演進示意圖
? 未規范化
學生表
學號 | 姓名 | 聯系方式 | 系名稱 | 愛好 | 擅長課程
1 | 張三 | 1380000,1391111 | 計算機系 | 足球 | 數學
問題:
聯系方式不原子化(違反 1NF)
姓名只依賴學號,不依賴課程號(違反 2NF)
系名稱依賴于系編號,而不是直接依賴學號(違反 3NF)
愛好和課程是獨立的多值依賴(違反 4NF)
? 第一范式 (1NF)
解決字段不可再分 → 拆分聯系方式
學生表
學號 | 姓名 | 聯系方式 | 系編號 | 系名稱 | 愛好 | 擅長課程
1 | 張三 | 1380000 | 01 | 計算機 | 足球 | 數學
1 | 張三 | 1391111 | 01 | 計算機 | 足球 | 數學
? 第二范式 (2NF)
解決部分依賴 → 拆分“學生”和“選課”
學生表
學號 | 姓名 | 系編號選課表
學號 | 課程號 | 成績
? 第三范式 (3NF)
解決傳遞依賴 → 把系名稱單獨拆表
學生表
學號 | 姓名 | 系編號系別表
系編號 | 系名稱選課表
學號 | 課程號 | 成績
? 第四范式 (4NF)
解決多值依賴 → 愛好、擅長課程單獨拆表
學生表
學號 | 姓名 | 系編號系別表
系編號 | 系名稱選課表
學號 | 課程號 | 成績學生_愛好表
學號 | 愛好學生_課程表
學號 | 擅長課程
📌 最終結果:
每張表結構更清晰,避免冗余和異常(插入、更新、刪除異常)。
實際項目中常用到 3NF,4NF 更多是學術或復雜業務場景。