1. 程式人生 > >資料庫設計三正規化

資料庫設計三正規化

第一正規化(1NF):強調的是列的原子性,即列不能夠再分成其他幾列。

問:怎麼知道列還能不能分?

答:靠生活常識與經驗

舉例1

id

地址

1

中國廣東

2

中國雲南

 地址這列還可以拆分:國籍,省區

舉例2

客戶表

username 姓名
sex 性別
telphone 電話
address 地址

電話可以拆分成:家庭電話,辦公電話

地址可以拆分成:家庭地址,公司地址

第二正規化(2NF)

1、符合第一正規化

2、有主鍵

3、非主鍵列必須完全依賴於主鍵,而不能只依賴於主鍵的一部分。

問:核心是什麼?

答:每一列不可拆分+每一列與主鍵有完全的依賴。

問:什麼時候會出現與主鍵是部分依賴呢?

答:當主鍵是多個列組成的時候。

舉例1:

學生證 名稱 學生證號 學生證辦理時間 借書證名稱 借書證號 借書證辦理時間

改成2張表如下

學生證表

學生證 學生證號 學生證辦理時間

借書證表

借書證 借書證號 借書證辦理時間

舉例2:

訂單詳情OrderDetail
OrderId 訂單編號
ProductId 商品編號
UnitPrice 單價
Discount 折扣
Quantity 數量
ProductName 商品名稱

主鍵:表中經常有一個列或多列的組合,其值能唯一地標識表中的每一行。

因為我們知道在一個訂單中可以訂購多種產品,所以單單一個 OrderID 是不足以成為主鍵的,主鍵應該是(OrderID,ProductID)

顯而易見 Discount(折扣),Quantity(數量)完全依賴於主鍵(OderID,ProductID),而 UnitPrice,ProductName 只依賴於 ProductID。所以 OrderDetail 表不符合 2NF。不符合 2NF 的設計容易產生冗餘資料。

可以把【OrderDetail】表拆分為【OrderDetail】(OrderID,ProductID,Discount,Quantity)和【Product】(ProductID,UnitPrice,ProductName)來消除原訂單表中UnitPrice,ProductName多次重複的情況。

訂單詳情表 OrderDetail
OrderId 訂單編號
ProductId 產品編號
Discount 折扣
Quantity 數量
產品表 Product
Productid 產品編號
UnitPrice 價格
ProductName 產品名稱

第三正規化

1、符合第二正規化

2、非主鍵列必須直接依賴於主鍵,不能存在傳遞依賴。即不能存在:非主鍵列 A 依賴於非主鍵列 B,非主鍵列 B 依賴於主鍵的情況。

考慮一個訂單表【Order】(OrderID,OrderDate,CustomerID,CustomerName,CustomerAddr,CustomerCity)主鍵是(OrderID)。 其中 OrderDate,CustomerID,CustomerName,CustomerAddr,CustomerCity 等非主鍵列都完全依賴於主鍵(OrderID),所以符合 2NF。

不過問題是 CustomerName,CustomerAddr,CustomerCity 直接依賴的是 CustomerID(非主鍵列),而不是直接依賴於主鍵,它是通過傳遞才依賴於主鍵,所以不符合 3NF。 通過拆分【Order】為【Order】(OrderID,OrderDate,CustomerID)和【Customer】(CustomerID,CustomerName,CustomerAddr,CustomerCity)從而達到 3NF。

總結:

第一正規化:原子性

第二正規化:完全依賴主鍵

第三正規化:完全依賴主鍵中沒有傳遞依賴