1. 程式人生 > >【轉載】關系型數據庫設計範式

【轉載】關系型數據庫設計範式

異常 AD gpo nts 屬性 sharp rst CA 都是

為了建立冗余較小、結構合理的關系數據庫,設計關系數據庫時必須遵循一定的規則, 即關系數據庫的設計範式。

第一範式(First Normal Form, 1NF)

關系型數據庫的第一範式要求:

  • 所有字段都是不可分割的

舉例來說,客戶數據表中包含客戶名和地址,地址由城市和街道組成。應用經常需要分別訪問城市或街道字段。

數據表customers(name,city, street)是符合第一範式的,而數據表customers(name,address)則不滿足第一範式的要求。

定義一個滿足第一範式的數據表:

courses(student_id, course_id, school_name, president, credit)
primary key(student_id, course_id)

上表仍然存在四個問題:

  • 數據冗余: school_name, president屬性重復出現

  • 插入異常: 若一個新建school沒有開始招生則不能加入數據表中

  • 刪除異常: 若一學院所有學生均畢業,則該學院信息消失

  • 修改異常: 若一學院院長更換,則需修改該學院所有學生的數據;

若一學生轉院則需修改其所選所有課程的數據。

第二範式(Second Normal Form, 2NF)

第二範式是在第一範式的基礎上定義的,它要求:

  • 表的設計滿足第一範式

  • 除主鍵外所有屬性完全函數依賴於主鍵

候選碼是函數決定所有非主屬性的最小集合,但不排除候選碼的真子集決定某些而非全部非主屬性的情況.

而2NF禁止候選碼的真子集函數決定任何非主屬性.

如上文數據表:

courses(student_id, course_id, school_name, president, credit)
primary key(student_id, course_id)

school_name和president屬性依賴於student_id屬性,不依賴於course_id屬性。

也就是說school,president屬性部分函數依賴於主鍵,不滿足第二範式的要求。

若將上表拆分為兩個數據表:

courses(student_id, course_id, credit)
primary key(student_id, course_id)

students(student_id, school_name, president)
primary key(student_id)

拆分後的數據表滿足了第二範式的要求。

現在分析一下,第一範式沒有解決的四個問題:

  • 數據冗余: 減少了school_name和president重復出現的次數

  • 插入異常: 未解決

  • 刪除異常: 未解決

  • 修改異常: 解決了學生轉院的問題,未解決院長更換的問題

第三範式(Third Normal Form, 3NF)

第三範式定義在第二範式的基礎上:

  • 表的設計滿足第二範式的要求

  • 除非主屬性直接依賴於主鍵

看上文數據表的定義

students(student_id, school_name, president)
primary key(student_id)

存在傳遞函數依賴student_id->school_name->president,不滿足第三範式。

進行進一步拆分:

courses(student_id, course_id, credit)
primary key(student_id, course_id)

students(student_id, school_name)
primary key(student_id)

schools(school_name, president)
primary key

拆分後消除了傳遞函數依賴。

分析第三範式對上述四個問題處理。

  • 數據冗余: 除了主鍵外所有屬性只出現一次

  • 刪除異常: 允許刪除所有學生而保留學院信息

  • 插入異常: 允許建立沒有學生的學院

  • 更新異常: 更換院長,學生轉院均只需修改一條記錄

第三範式基本上可以解決上述問題。

BCNF

BC(Boyce-Codd)範式在3NF的基礎上進一步消除了傳遞依賴.

BCNF要求:

  • 關系模式符合3NF

  • 函數依賴集F中所有函數依賴X->F, 左部X必須包含R的所有候選碼.

即所有候選碼都直接決定所有非主屬性.

BCNF分解算法

給定關系模式R和其上的函數依賴集F, 將R進行滿足BCNF的無損連接分解:

  1. 置初值p = {R}

  2. 檢查p中的關系模式若均滿足BCNF則停止分解, 否則重復執行3.

  3. 在p中選出不滿足BCNF的關系模式S, 其中必有非平凡依賴B->C, 且B不是S的候選碼.將S分解為S1= {B,C}和S2 = R - {C}, 用S1,S2代替p中S的位置.

示例:

R = {A, B, C} F = {A->B, B->C}

候選碼A, 函數依賴B->C, 因為B不是Candidate Key所以要進行分解:

{B, C} {A, B}

第四範式(Forth Normal Form, 4NF)

4NF要求:

  • 必須滿足BCNF

  • 非主屬性不能存在多值

示例:

phone(user_id,  phone, cell)

若某用戶有多個phone同時又有多個cell時此表設計顯然不合理.

可以采用如下的拆分方案:

phone(user_id, phone, type)

拆分後的數據表滿足了4NF.

【轉載】關系型數據庫設計範式