主要有6種范式:第一范式(1NF),第二范式(2NF),第三范式(3NF),巴德斯科范式(BCNF),第四范式(4NF),第五范式(5NF),按從左至右的順序一種比一種要求更嚴格。要符合某一種范式必須也滿足它前邊的所有范式。一般項目的數據庫設計達到3NF就可以了,而且可根據具體情況適當增加冗余,不必教條地遵守所謂規范。
從范式所允許的函數依賴方面進行比較,四種范式之間的關聯如下圖所示。
1、第一范式(1NF)無重復的列
所謂第一范式(1NF)是指數據庫表的每一列都是不可分割的基本數據項,同一列中不能同時有多個值,即實體中的某個屬性不能有多個值或者不能有重復的屬性。如果出現重復的屬性,就可能需要定義一個新的實體,新的實體由重復的屬性構成,新實體與原實體之間為一對多關系。在第一范式(1NF)中表的每一行只包含一個實例的信息。簡而言之,第一范式就是無重復的列。
在任何一個關系數據庫中,第一范式(1NF)是對關系模式的基本要求,不滿足第一范式(1NF)的數據庫就不是關系數據庫。在當前的任何關系數據庫管理系統(DBMS)中,不可能做出不符合第一范式的數據庫,因為這些DBMS不允許你把數據庫表的一列再分成二列或多列。因此,你想在現有的DBMS中設計出不符合第一范式的數據庫都是不可能的。
例如:
一張學生表Student(stuNo,stuName,age,age,sex)是不符合第一范式的,因為有重復列age屬性。去除重復列age以后的Student(stuNo,stuName,age,sex)是符合第一范式的。
2、第二范式(2NF)屬性完全依賴於主鍵 [ 消除部分子函數依賴 ]
第二范式(2NF)是在第一范式(1NF)的基礎上建立起來的,即滿足第二范式(2NF)必須先滿足第一范式(1NF)。第二范式(2NF)要求數據庫表中的每個實例或行必須可以被唯一地區分。為實現區分通常需要為表加上一個列,以存儲各個實例的唯一標識。例如員工信息表中加上了員工編號(emp_id)列,因為每個員工的員工編號是唯一的,因此每個員工可以被唯一區分。這個唯一屬性列被稱為主關鍵字或主鍵、主碼。
第二范式(2NF)要求實體的屬性完全依賴於主關鍵字。所謂完全依賴是指不能存在僅依賴主關鍵字一部分的屬性,如果存在,那么這個屬性和主關鍵字的這一部分應該分離出來形成一個新的實體,新實體與原實體之間是一對多的關系。為實現區分通常需要為表加上一個列,以存儲各個實例的唯一標識。簡而言之,第二范式就是屬性完全依賴於主鍵。
這里說的主關鍵字可能不只有一個,有些情況下是存在聯合主鍵的,就是主鍵有多個屬性。
例如:
以學生選課為例,每個學生都可以選課,並且有這一門課程的成績,那么如果將這些信息都放在一張表StuGrade(stuNo,stuName,age,sex,courseNo,courseName,credit,score)。
如果不仔細看,我們會以為這張表的主鍵是stuNo,但是當我們看到最后一個score屬性以后,在想想如果沒有課程信息,那么哪里有學生成績信息呢。所以這張表的主鍵是一個聯合主鍵(stuNo,corseNo),這個聯合屬性能夠唯一確定score屬性。那么再看其他信息,比如stuName只需要stuNo就能夠唯一確定,courseName只需要courseNo就能夠唯一確定,因此這樣就存在了部分依賴,不符合第二范式。如果要讓學生課程成績信息滿足第二范式,那么久需要將這張表拆分成多張表,一張學生表Studnet(stuNo,stuName,age,sex),一張課程表Course(courseNo,courseName,credit),還有最后一張學生課程成績表StuGrade(stuNo,courseNo,score)。
3、 第三范式(3NF):屬性不依賴於其它非主屬性 [ 消除傳遞依賴 ]
定義: 如果關系模式R為2NF,並且R中的每一個非主屬性都不傳遞依賴於R的某個候選關鍵字,則稱R是第三范式的,簡記為3NF。
滿足第三范式(3NF)必須先滿足第二范式(2NF)。簡而言之,第三范式(3NF)要求一個數據庫表中不包含已在其它表中已包含的非主關鍵字信息。
舉例3:
每一個員工都有一個所屬部門,假如有一個員工信息表Employee(emp_id,emp_name,emp_age,dept_id,dept_name,dept_info)。
這張員工信息表的主鍵是emp_id,因為這個屬性能夠唯一確定其他所有屬性,比如知道員工編號emp_id以后,肯定能夠知道員工姓名,所屬部門編號,部門名稱和部門介紹。所以這里dept_id不是主屬性,而是非主屬性。但是,我們又可以發現dept_name,dept_info這兩個屬性也可以由dept_id這個非主屬性決定,即dept_name依賴dept_id,而dept_id依賴emp_id,這樣就存在了傳遞依賴。而且我們可以看出傳遞依賴的一個明顯缺點就是數據冗余非常嚴重。
那么如何解決傳遞依賴問題,其實非常簡單,我們只需要將dept_name,dept_info這連個屬性刪除就可以了,即Employee(emp_id,emp_name,emp_age,dept_id),然后再創建一個部門表Dept(dept_id,dept_name,dept_info)。
這樣如果要搜索某一個員工的部門信息dept_info,可以通過數據庫連接來實現,查詢語句如下:
select e.emp_id,e.emp_name,d.dept_name from Employee e,Dept d where e.dept_id=d.dept_id
4、Boyce-Codd范式(BCNF)
定義: 如果關系模式R為1NF,並且R中的每一個函數依賴X→Y(YÏX),必有X是R的超關鍵字,則稱R是Boyce-Codd范式的,簡記為BCNF。
從BCNF的定義中,可以明顯地得出如下結論:
(1) 所有非主屬性對鍵是完全函數依賴;
(2) 所有主屬性對不包含它的鍵是完全函數依賴;
(3)沒有屬性完全函數依賴於非鍵的任何屬性組合。
與2NF,3NF的定義不同,BCNF的定義直接建立在1NF的基礎上。但實質上BCNF是3NF的改進形式。3NF僅考慮了非主屬性對鍵的依賴情況,BCNF把主屬性對鍵的依賴情況也包括進去。BCNF要求滿足的條件比3NF所要求的更高。如果關系模式R是BCNF的,那么R必定是3NF,反之,則不一定成立。
【例2.43】 續前例2.42(學號S#,課程號C#,成績G,任課教師TN,教師專長TS),判斷兩個3NF關系模式R3={C#,TN},R4={TN,TS}是否為BCNF。
解:在關系模式R3中有函數依賴C#→TN,決定因素C#是R3的鍵;
在關系模式R4中有函數依賴TN→TS,決定因素TN是R4的鍵;
R3,R4都滿足BCNF的定義,所以,這兩個關系模式都是BCNF。
【例2.44】配件管理關系模式 WPE(WNO,PNO,ENO,QNT)分別表倉庫號,配件號,職工號,數量。有以下條件 a.一個倉庫有多個職工。 b.一個職工僅在一個倉庫工作。 c.每個倉庫里一種型號的配件由專人負責,但一個人可以管理幾種配件。 d.同一種型號的配件可以分放在幾個倉庫中。 分析:由以上得 PNO 不能確定QNT,由組合屬性(WNO,PNO)來決定,存在函數依賴(WNO,PNO) -> ENO。由於每個倉庫里的一種配件由專人負責,而一個人可以管理幾種配件,所以有組合屬性(WNO,PNO)才能確定負責人,有(WNO,PNO)-> ENO。因為 一個職工僅在一個倉庫工作,有ENO -> WNO。由於每個倉庫里的一種配件由專人負責,而一個職工僅在一個倉庫工作,有 (ENO,PNO)-> QNT。 找一下候選關鍵字,因為(WNO,PNO) -> QNT,(WNO,PNO)-> ENO ,因此 (WNO,PNO)可以決定整個元組,是一個候選關鍵字。根據ENO->WNO,(ENO,PNO)->QNT,故(ENO,PNO)也能決定整個元組,為另一個候選關鍵字。屬性ENO,WNO,PNO 均為主屬性,只有一個非主屬性QNT。它對任何一個候選關鍵字都是完全函數依賴的,並且是直接依賴,所以該關系模式是3NF。 分析一下主屬性。因為ENO->WNO,主屬性ENO是WNO的決定因素,但是它本身不是關鍵字,只是組合關鍵字的一部分。這就造成主屬性WNO對另外一個候選關鍵字(ENO,PNO)的部 分依賴,因為(ENO,PNO)-> ENO但反過來不成立,而P->WNO,故(ENO,PNO)-> WNO 也是傳遞依賴。 雖然沒有非主屬性對候選關鍵遼的傳遞依賴,但存在主屬性對候選關鍵字的傳遞依賴,同樣也會帶來麻煩。如一個新職工分配到倉庫工作,但暫時處於實習階段,沒有獨立負責對某些配件的管理任務。由於缺少關鍵字的一部分PNO而無法插入到該關系中去。又如某個人改成不管配件了去負責安全,則在刪除配件的同時該職工也會被刪除。 解決辦法:分成管理EP(ENO,PNO,QNT),關鍵字是(ENO,PNO)工作EW(ENO,WNO)其關鍵字是ENO 缺點:分解后函數依賴的保持性較差。如此例中,由於分解,函數依賴(WNO,PNO)-> ENO 丟失了, 因而對原來的語義有所破壞。沒有體現出每個倉庫里一種部件由專人負責。有可能出現 一部件由兩個人或兩個以上的人來同時管理。因此,分解之后的關系模式降低了部分完整性約束。
注意點:
- 數據庫連接會帶來一部分的性能損失
- 並不是數據庫范式越高越高
- 有時會在數據冗余與范式之間做出權衡,在實際的數據庫開發過程中,往往會允許一部分的數據冗余來減少數據庫連接。