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
- 每一個 record 都是 unique, 沒有重復的 rows
- 每一個 cell 只有一個 value (atomic).
2NF
- 滿足 1 NF
- 沒有 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_name
去 student
table 裡。
3NF
- 滿足 2NF
- 沒有 transitive dependencies, 即 non-key columns 不能 depend on 其他 non-key columns.
例如一個課程表:
lesson_id (PK) | room_id | start_time | end_time | instructor_id | instructor_name |
---|
因為 instructor_id
和 instructor_name
這兩個 non-key columns depend on each other, 所以不符合 3NF。
解決方法是拆 instructor_name
去 instructor
table 裡。
目前,這個部落格儘可能使用中文書寫。但由於我所學時的語言是英文,若將其翻譯成中文,可能會因水平所限,顯得有些彆扭。加上「行」和「列」在不同地區有歧義,因此我選擇放棄,只方便自己的回顧算了。