Database normalization – 3NF 筆記

Database normalization 是關係型數據庫設計重要的重要概念。這裡嘗試用簡單的表述重溫 3NF (第三正規化)。

Database normalization是關係型數據庫設計的重要概念,通常需要理解到3NF(第三正規化)。

我個人並不擅長背誦理論,所以若要問我 3NF 的具體含義,我還得透過Google尋找答案。雖然我無法清楚說明,但在設計 Table 時,我會有種「理所當然應該這麼做,否則會很奇怪」的感覺,因此,我有信心能做到符合 3NF 的要求。

然而,我在實際設計時,並不會刻意追求達到多少NF。

很多時候,我們追求的是簡單和方便,有時需要做一些denormalization的取捨。

另外,與OLTP系統不同,在資料倉儲這類OLAP的系統中,設計是偏向dimensional model,而非 normalization。

不少系統 (最佳例子仍是 Data warehouse) 需要做 ETL來定期接收外部系統的 data (e.g. interface file),而在接收時,往往會先暫存在staging tables中。這些 tables 的設計往往是照抄 interface file 的 data definition 而來的,別人給我什麼,我便照單吃下,不會做 normalization。


不過,我還是重溫一下3NF,簡單地做下筆記。

1 NF: Remove multivalued attributes

2 NF: 1NF + remove partial dependencies

3 NF: 2NF + remove transitive dependencies

1NF

  1. 每一個 record 都是 unique, 沒有重復的 rows
  2. 每一個 cell 只有一個 value (atomic).

2NF

  1. 滿足 1 NF
  2. 沒有 partial dependencies. 視乎 Primary key 由多少個 column 組成:
    • 1 個的話,自動符合
    • 多個的話,即 composite primary key. 那所有 non-key columns 必須 dependent on entire primary keys (若不是完全依賴,便存在 partial dependencies)

例如有一個成績表:

student_id (PK) course_id (PK) student_name grading

這裡 student_id (PK)course_id (PK) 組成了 composite primary key。

但當中 non-key column student_name 只是 depends on student_id (PK), 而沒有 depends on course_id (PK)

因其不是 dependent on entire primary keys, 所以存在 partial dependencies, 不符合 2NF 要求。

解決方法是拆 student_namestudent table 裡。

3NF

  1. 滿足 2NF
  2. 沒有 transitive dependencies, 即 non-key columns 不能 depend on 其他 non-key columns.

例如一個課程表:

lesson_id (PK) room_id start_time end_time instructor_id instructor_name

因為 instructor_idinstructor_name 這兩個 non-key columns depend on each other, 所以不符合 3NF。

解決方法是拆 instructor_nameinstructor table 裡。


目前,這個部落格儘可能使用中文書寫。但由於我所學時的語言是英文,若將其翻譯成中文,可能會因水平所限,顯得有些彆扭。加上「行」和「列」在不同地區有歧義,因此我選擇放棄,只方便自己的回顧算了。

comments powered by Disqus