資料庫正規化(Database Normalization)完整指南:新手必讀

更新日期: 2025 年 3 月 4 日

在設計關聯式資料庫時,資料的組織方式直接影響到查詢效能、資料一致性,以及維護的難易度

如果沒有妥善規劃,可能會出現重複數據、異常更新,甚至導致資料不一致的情況。

為了避免這些問題,「資料庫正規化」(Database Normalization) 應運而生。

本篇文章將為新手詳細介紹資料庫正規化的概念、優勢、不同的正規化階段(范式),以及實際應用方式

希望讀完後,你能夠理解正規化的目的,並應用於你的資料庫設計中。


什麼是資料庫正規化?

資料庫正規化是一種結構化設計方法,用來將資料表分解成更小、更具邏輯性的表格,以減少冗餘、避免異常(Anomalies),並提高資料一致性

這個過程通常分為不同的階段(范式,Normal Forms, NF),每個階段都進一步優化資料表的結構。

舉個簡單的例子:

假設我們有一張「學生」資料表:

學生ID姓名課程名稱課程教師
001小明資料庫設計張老師
002小華資料庫設計張老師
003小美網頁設計王老師

這樣的設計存在問題,例如:

  • 資料重複:同一位老師的名字被多次存儲。
  • 更新異常:如果張老師改名,則所有相關記錄都必須更新。
  • 刪除異常:如果某課程只有一位學生,刪除該學生時,課程資訊也會被刪除。

這些問題可以透過正規化來解決。


為什麼要進行正規化?

進行資料庫正規化有幾個主要目的:

  1. 減少資料冗餘(Redundancy)
    • 避免相同資料被重複存儲,減少資料庫的儲存空間浪費。
  2. 消除異常(Anomalies)
    • 插入異常(Insertion Anomaly):例如,要新增一門新課程但沒有學生,則無法插入課程資料。
    • 更新異常(Update Anomaly):例如,修改教師名稱時,需修改多個記錄,容易導致資料不一致。
    • 刪除異常(Deletion Anomaly):例如,若刪除某門課程的最後一位學生,該課程的資料可能會遺失。
  3. 提高資料一致性與完整性(Consistency & Integrity)
    • 透過將資料拆分到不同的表,確保數據的正確性。
  4. 提高查詢效能
    • 雖然正規化後可能需要更多的 JOIN 操作,但對於頻繁更新的系統,正規化能減少更新的負擔,提高效率。

資料庫正規化的不同階段(范式)

正規化通常被分為多個級別,每個級別稱為「范式」(Normal Form, NF)。

目前常見的范式有第一范式(1NF)、第二范式(2NF)、第三范式(3NF),還有進一步的BCNF、第四范式(4NF)與第五范式(5NF)

以下是各個范式的詳細解釋:

第一范式(1NF)— 消除重複欄位

條件:

每個欄位只能存放一個值,不能存放一組值或多個資料。

例如,在「課程」欄位中,不能同時存放「資料庫設計、網頁設計」,而是要拆成兩筆獨立的記錄,每筆只包含一個課程名稱。

每一筆資料(每一行)都必須有一個能夠唯一識別它的「身份證明」,通常是「主鍵」(Primary Key)。


也就是說,不能有完全相同的記錄重複出現在表格中,而是要有一個獨特的識別碼(像是學生ID)來區分不同的資料。

示例(未滿足 1NF)

學生ID姓名課程名稱
001小明資料庫設計, 網頁設計
002小華資料庫設計

改正後(滿足 1NF)

學生ID姓名課程名稱
001小明資料庫設計
001小明網頁設計
002小華資料庫設計

這樣的設計確保每個欄位只存儲單一值

第二范式(2NF)— 消除部分依賴

條件:

必須滿足 1NF

也就是說,資料表已經符合第一范式(1NF),每個欄位都只能存放單一值,不能有重複的欄位或一欄存多個值的情況。

表內所有非主鍵欄位,都必須完全依賴於主鍵,而不能只是部分依賴

這表示資料表中的每個欄位都應該完整地依賴於主鍵,不能只依賴其中的一部分。

如果一張表的主鍵是由多個欄位組成(複合主鍵),那麼表中的其他欄位不能只依賴其中一部分,而是要依賴整個主鍵。

示例(未滿足 2NF)

學生ID課程名稱課程教師
001資料庫設計張老師
002資料庫設計張老師

這張表的主鍵由「學生ID + 課程ID」組成,因為一個學生可以選修多門課,而一門課也可以有多個學生修課。

「課程名稱」這個欄位只依賴「課程ID」,並沒有依賴「學生ID」這部分,因此它是「部分依賴」,違反了 2NF。

改正後(滿足 2NF) 拆成兩張表:

  1. 學生表
學生ID課程名稱
001資料庫設計
002資料庫設計
  1. 學校資訊表
課程名稱課程教師
資料庫設計張老師

這樣的設計確保每個表中的非主鍵欄位完全依賴於主鍵

第三范式(3NF)— 消除傳遞依賴

條件:

必須滿足 2NF

這表示資料表已經符合第二范式(2NF),也就是:

所有非主鍵欄位只能直接依賴主鍵,而不能透過其他非主鍵欄位間接依賴。

這表示資料表中的非主鍵欄位(例如學生的地址、學校名稱)應該直接由主鍵決定,而不能透過另一個非主鍵欄位來決定。

示例(未滿足 3NF)

學生ID學生姓名學校名稱
001小明台灣大學
002小華台灣大學

這裡,「學校名稱」並不是直接依賴「學生ID」,而是透過「學生姓名」間接依賴,因此違反 3NF。

改正後(滿足 3NF) 拆成兩張表:

  1. 學生表
學生ID學生姓名
001小明
002小華
  1. 學校資訊表
學生姓名學校名稱
小明台灣大學
小華台灣大學

這樣就確保了所有非主鍵欄位都直接依賴於主鍵


為什麼稱為「范式」?

「范式」這個詞來自於數學和科學領域,通常指的是一種標準化的模型或範例

在資料庫領域,范式(Normal Form)表示資料表達結構的一種「規範化形式」,用來確保數據儲存的最佳方式。

具體來說,稱為「范式」的原因有以下幾點:

  1. 提供一種標準(Standardization)
    • 正規化過程透過一系列規則(如 1NF, 2NF, 3NF…)來標準化資料表的設計,避免不必要的數據冗餘與異常。
  2. 來自數學的概念
    • 關聯式資料庫的設計基礎源於數學中的「關係代數」,而「Normal Form」在數學中表示某種標準化的狀態,因此被引入資料庫設計中,稱為「范式」。
  3. 強調最佳實踐
    • 資料庫范式是一種指導方針,讓開發者知道如何設計高效、可擴展的資料庫架構。
  4. 來自英文翻譯
    • Normal Form 的「Normal」指的是「標準化」、「正規化」的概念,而「Form」指的是「形式、格式」。在中文裡,「范式」這個詞最接近「標準化的模式」,因此被用來翻譯 Normal Form。

范式的作用

不同的范式代表不同程度的資料庫正規化,每一級范式都比前一級更進一步地優化資料結構:

  • 第一范式(1NF):消除重複欄位,使每個欄位只能存放「單一值」。
  • 第二范式(2NF):消除部分依賴,確保所有非主鍵欄位完全依賴於主鍵。
  • 第三范式(3NF):消除傳遞依賴,確保所有非主鍵欄位直接依賴主鍵,而非透過其他欄位間接依賴。

進一步還有 BCNF(Boyce-Codd Normal Form)、第四范式(4NF)、第五范式(5NF),這些較高級的范式在更複雜的情境下使用。


結論

資料庫正規化是一個重要的設計原則,能夠幫助我們降低資料冗餘、提升數據一致性、避免異常發生

然而,在實務應用中,有時過度正規化可能會導致查詢效能下降,因此要根據實際需求適度進行正規化與反正規化的權衡。

希望這篇文章能幫助你理解正規化的概念與應用方式,讓你的資料庫設計更加高效且穩健!🚀

Similar Posts