資料庫設計三正規化
第一正規化(1NF):強調的是列的原子性,即列不能夠再分成其他幾列。
問:怎麼知道列還能不能分?
答:靠生活常識與經驗
舉例1
id |
地址 |
1 |
中國廣東 |
2 |
中國雲南 |
地址這列還可以拆分:國籍,省區
舉例2
客戶表
username | 姓名 |
sex | 性別 |
telphone | 電話 |
address | 地址 |
電話可以拆分成:家庭電話,辦公電話
地址可以拆分成:家庭地址,公司地址
第二正規化(2NF)
1、符合第一正規化
2、有主鍵
3、非主鍵列必須完全依賴於主鍵,而不能只依賴於主鍵的一部分。
問:核心是什麼?
答:每一列不可拆分+每一列與主鍵有完全的依賴。
問:什麼時候會出現與主鍵是部分依賴呢?
答:當主鍵是多個列組成的時候。
舉例1:
學生證 名稱 | 學生證號 | 學生證辦理時間 | 借書證名稱 | 借書證號 | 借書證辦理時間 |
改成2張表如下
學生證表
學生證 | 學生證號 | 學生證辦理時間 |
借書證表
借書證 | 借書證號 | 借書證辦理時間 |
舉例2:
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多次重複的情況。
OrderId | 訂單編號 |
ProductId | 產品編號 |
Discount | 折扣 |
Quantity | 數量 |
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。
總結:
第一正規化:原子性
第二正規化:完全依賴主鍵
第三正規化:完全依賴主鍵中沒有傳遞依賴