資料庫設計正規化1——三正規化

深藍發表於2013-09-06

一講到資料庫設計,大家很容易想到的就是三正規化,但是第四、第五正規化又是什麼,不是很清楚,三正規化到底怎麼區分,也不清楚,作為資料庫設計的基礎概念,我再講解下資料庫正規化。

  Normal form Brief definition
1NF First normal form Table faithfully represents a relation, primarily meaning it has at least one candidate key
2NF Second normal form No non-prime attribute in the table is functionally dependent on a proper subset of any candidate key
3NF Third normal form Every non-prime attribute is non-transitively dependent on every candidate key in the table. The attributes that do not contribute to the description of the primary key are removed from the table. In other words, no transitive dependency is allowed.
EKNF Elementary Key Normal Form Every non-trivial functional dependency in the table is either the dependency of an elementary key attribute or a dependency on a superkey
BCNF Boyce–Codd normal form Every non-trivial functional dependency in the table is a dependency on a superkey
4NF Fourth normal form Every non-trivial multivalued dependency in the table is a dependency on a superkey
5NF Fifth normal form Every non-trivial join dependency in the table is implied by the superkeys of the table
DKNF Domain/key normal form Every constraint on the table is a logical consequence of the table's domain constraints and key constraints
6NF Sixth normal form Table features no non-trivial join dependencies at all (with reference to generalized join operator)

第一正規化 1NF First normal form

簡單說來就是每個表都應該有主鍵(唯一標識每一行),每個欄位應該是原子的不可再分的。

比如以下表不符合第一正規化,因為沒有主鍵,我們無法區分第一行和第三行資料。

Name Gender Contact Interest
Neil M Email:neil@ee.net,phone:1222456 Reading;Guitar
Devin M Email:studyzy@163.net,phone:13934563456 Swimming
Neil M Email:neil@ee.net,phone:1222456 Reading;Guitar

為了區分每一行資料,所以需要新增主鍵UserId,這樣就能區分出每一行資料來。

UserId Name Gender Contact Interest
1 Neil M Email:neil@ee.net,phone:1222456 Reading;Guitar
2 Devin M Email:studyzy@163.net,phone:13934563456 Swimming

但是這個表仍然不符合第一正規化,應該Contact欄位不是不可再分的,該欄位可以分為Email和Phone兩個欄位,所以我們表變為:

UserId Name Gender Email Phone Interest
1 Neil M neil@ee.net 1222456 Reading;Guitar
2 Devin M studyzy@163.net 13934563456 Swimming

這樣做以後我們的表仍然是不符合第一正規化的,應該Interest欄位不是原子的,裡面包含了一組資料,對於這個欄位,就不能像Contact一樣拆分成兩個欄位,應該Interest欄位裡面包含的物件是一樣的,而且一個使用者可以有無數多個興趣愛好。所以我們需要將該欄位單獨出來,形成新的表:

UserId Name Gender Email Phone
1 Neil M neil@ee.net 1222456
2 Devin M studyzy@163.net 13934563456

 

UserId Interest
1 Reading
1 Guitar
2 Swimming

現在這兩個表才滿足第一正規化。

第二正規化 2NF Second normal form

簡單說來就是在滿足第一正規化的情況下,非主鍵屬性應該完全依賴於候選鍵(候選關鍵字、唯一標識每一行資料的鍵,一個表存在多個候選鍵),而不應該依賴於候選鍵的部分。

比如以下的學生選課表,主鍵是學號和課程號,非主鍵屬性是選課的時間,系統確認的時間,所選課程的名字。

StudentId CourseId ChooseTime ConfirmTime CourseName
1 10 2013/8/26 2013/8/27 微積分
1 11 2013/8/27 2013/8/27 線性代數
2 10 2013/8/26 2013/8/27 微積分

這個表滿足第一正規化,因為StudentId+CourseId能夠唯一的標識每一行資料,而且每個屬性都是原子的,不可再分的。選課時間和系統確認時間完全依賴於主鍵,沒有問題。課程名稱只依賴於CourseId,不依賴於StudentId,所以不滿足第二正規化,需要將課程名稱獨立出來:

StudentId CourseId ChooseTime ConfirmTime
1 10 2013/8/26 2013/8/27
1 11 2013/8/27 2013/8/27
2 10 2013/8/26 2013/8/27

 

CourseId CourseName
10 微積分
11 線性代數

第三正規化 3NF Third normal form

簡單來說就是滿足第二正規化的情況下,非主鍵屬性應該完全依賴於候選鍵,不應該依賴於其他非候選鍵。

比如以下的學生表,主鍵是學號,非主鍵屬性為學生姓名、所在院系Id,所在院系名。

StudentId Name DepartmentId DepartmentName
1 Neil 21 Math
2 Devin 22 Computer

首先這個表滿足第二正規化,因為主鍵就一個欄位,所有非主鍵屬性都依賴於StudentId。但是該表不滿足第三正規化,因為院系名稱是依賴於院系ID的,院系ID在這個表中是非主鍵,依賴於學生ID,也就是傳遞依賴。

以上說的是資料庫設計中最基本的三正規化,大部分資料庫設計時,只需要滿足這三個正規化即可。接下來我還會寫一篇部落格講解下更高階的正規化。

相關文章