范式:英文名稱是 normal form,它是英國人 e.f.codd(關系數據庫的老祖宗)在上個世紀70年代提出關系數據庫模型后總結出來的,范式是關系數據庫理論的基礎,也是我們在設計數據庫結構過程中所要遵循的規則和指導方法。目前有跡可尋的共有8種范式,依次是:1nf,2nf,3nf,bcnf,4nf,5nf,dknf,6nf。通常所用到的只是前三個范式,即:第一范式(1nf),第二范式(2nf),第三范式(3nf)。下面就簡單介紹下這三個范式。
◆ 第一范式(1nf):強調的是列的原子性,即列不能夠再分成其他幾列。
考慮這樣一個表:【聯系人】(姓名,性別,電話)
如果在實際場景中,一個聯系人有家庭電話和公司電話,那么這種表結構設計就沒有達到 1nf。要符合 1nf 我們只需把列(電話)拆分,即:【聯系人】(姓名,性別,家庭電話,公司電話)。1nf 很好辨別,但是 2nf 和 3nf 就容易搞混淆。
◆ 第二范式(2nf):首先是 1nf,另外包含兩部分內容,一是表必須有一個主鍵;二是沒有包含在主鍵中的列必須完全依賴于主鍵,而不能只依賴于主鍵的一部分。
考慮一個訂單明細表:【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多次重復的情況。
◆ 第三范式(3nf):首先是 2nf,另外非主鍵列必須直接依賴于主鍵,不能存在傳遞依賴。即不能存在:非主鍵列 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。
第二范式(2nf)和第三范式(3nf)的概念很容易混淆,區分它們的關鍵點在于,2nf:非主鍵列是否完全依賴于主鍵,還是依賴于主鍵的一部分;3nf:非主鍵列是直接依賴于主鍵,還是直接依賴于非主鍵列。
范式:英文名稱是 normal form,它是英國人 e.f.codd(關系數據庫的老祖宗)在上個世紀70年代提出關系數據庫模型后總結出來的,范式是關系數據庫理論的基礎,也是我們在設計數據庫結構過程中所要遵循的規則和指導方法。目前有跡可尋的共有8種范式,依次是:1nf,2nf,3nf,bcnf,4nf,5nf,dknf,6nf。通常所用到的只是前三個范式,即:第一范式(1nf),第二范式(2nf),第三范式(3nf)。下面就簡單介紹下這三個范式。
◆ 第一范式(1nf):強調的是列的原子性,即列不能夠再分成其他幾列。
考慮這樣一個表:【聯系人】(姓名,性別,電話)
如果在實際場景中,一個聯系人有家庭電話和公司電話,那么這種表結構設計就沒有達到 1nf。要符合 1nf 我們只需把列(電話)拆分,即:【聯系人】(姓名,性別,家庭電話,公司電話)。1nf 很好辨別,但是 2nf 和 3nf 就容易搞混淆。
◆ 第二范式(2nf):首先是 1nf,另外包含兩部分內容,一是表必須有一個主鍵;二是沒有包含在主鍵中的列必須完全依賴于主鍵,而不能只依賴于主鍵的一部分。
考慮一個訂單明細表:【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多次重復的情況。
◆ 第三范式(3nf):首先是 2nf,另外非主鍵列必須直接依賴于主鍵,不能存在傳遞依賴。即不能存在:非主鍵列 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。
第二范式(2nf)和第三范式(3nf)的概念很容易混淆,區分它們的關鍵點在于,2nf:非主鍵列是否完全依賴于主鍵,還是依賴于主鍵的一部分;3nf:非主鍵列是直接依賴于主鍵,還是直接依賴于非主鍵列。