數據庫中的範式

 1NF:一個table中的列是不可再分的(即列的原子性)
      2NF:一個table中的行是可以唯一標示的,(即table中的行是不可以有重複的)
      3NF:一個table中列不依賴以另一個table中的非主鍵的列,還是不通俗!巨寒!!
              舉個例子吧:有一個部門的table,我們叫它tbl_department,
      它有這麼幾列(dept_id(pk),dept_name,dept_memo...)
                               
      有一個員工table,我們叫它tbl_employee,在這個table中有一列dept_id(fk)描述關於部門的信息,若tbl_employee要滿足3NF,
                                則在tbl_employee中就不得再有除dept_id列的其它有關部門信息的列!
      一般數據庫的設計滿足3NF即可!(個人覺得應該儘可能的滿足3NF,一家之言^_^)
      BCNF:通常認爲BCNF是修正的第三範式,它比3NF又進一步!
      4NF:
      5NF:將一個table儘可能的分割成小的塊,以排除在table中所有冗餘的數據
      範式簡介
      爲了回答上述問題,瞭解3NF、BCNF、4NF和5NF之間的區別很重要。以下爲每個範式的準確定義。
      第一範式(1NF)
      每個表必須有一個首要鍵,即最少的一組屬性,它與每條記錄一一對應。通過適當定義鍵屬性和非鍵屬性,刪除重複的組(不同記錄似乎需要不同次重複的數據種類)。注:每個屬性必須包含單獨一個值,而非一組值。
      第二範式(2NF)
      數據庫必須滿足1NF的所有要求。另外,如果一個表有一個複合鍵,所有屬性必須與整個鍵相關聯。而且,在表的多行之間多餘重複的數據被移動一個單獨的表中。
      第三範式(3NF)
      存儲在表中的數據不得依賴表的任何域,必須唯一依賴於首要鍵。數據庫必須滿足2NF的所有要求。既依賴首要鍵,又依賴其它域的數據被移動到一個單獨的表中。
      Boyce-Codd範式(BCNF)
      除對一個候選鍵擴展集(稱作一個超級鍵)存在屬性函數依賴外,不存在其它非平凡函數依賴。
      第四範式(4NF)
      除對一個候選鍵擴展集存在屬性組函數依賴外,不存在其它非平凡多值函數依賴。如果且只有一個表符合BCNF,同時多值依賴爲函數依賴,此表才符合第四範式。4NF刪除了不必要的數據結構:多值依賴。
      第五範式(5NF)
      不得存在不遵循鍵約束的非平凡連接依賴。如果且只有一個表符合4NF,同時其中的每個連接依賴被候選鍵所包含,此表才符合第五依賴。
      數據庫範式
      注:
      表在定義中被稱爲關係,記作R
      字段在定義中被稱作屬性
      模式:數據庫中有三種模式,外模式,內模式,模式
      粗體是關鍵字的意思
      斜體爲外鍵

      第一範式
      定義:如果關係R 中所有屬性的值域都是單純域,那麼關係模式R是第一範式的
      那麼符合第一模式的特點就有
      1)有主關鍵字
      2)主鍵不能爲空,
      3)主鍵不能重複,
      4)字段不可以再分
      例如:
      StudyNo   |   Name   |   Sex   |   Contact
      20040901      john         Male      Email:[email protected],phone:222456
      20040901      mary         famale   email:[email protected] phone:123455
      以上的表就不符合,第一範式:主鍵重複(實際中數據庫不允許重複的),而且Contact字段可以再分
      所以變更爲正確的是
      StudyNo |   Name   |   Sex   |      Email         |      Phone
      20040901     john       Male       [email protected]            222456
      20040902     mary       famale     [email protected]            123455

      第二範式:
      定義:如果關係模式R是第一範式的,而且關係中每一個非主屬性不部分依賴於主鍵,稱R是第二範式的。
      所以第二範式的主要任務就是
      滿足第一範式的前提下,消除部分函數依賴。
      StudyNo | Name | Sex |    Email    | Phone | ClassNo| ClassAddress
      01        john   Male [email protected]   222456    200401      A樓2
      01        mary famale [email protected]   123455    200402      A樓3
      這個表完全滿足於第一範式,
      主鍵由StudyNo和ClassNo組成,這樣才能定位到指定行
      但是,ClassAddress部分依賴於關鍵字(ClassNo-〉ClassAddress),
      所以要變爲兩個表
      表一
      StudyNo | Name | Sex |     Email        | Phone |   ClassNo
            01    john     Male     [email protected]      222456    200401    
            01    mary     famale   [email protected]      123455    200402   
      表二
      ClassNo | ClassAddress
      200401      A樓2
      200402      A樓3


      第三範式:
      滿足第二範式的前提下,消除傳遞依賴。
      例:
      StudyNo | Name | Sex |    Email    | bounsLevel | bouns
      20040901 john   Male   [email protected]     優秀       $1000
      20040902 mary   famale [email protected]      良        $600
      這個完全滿足了第二範式,但是bounsLevel和bouns存在傳遞依賴
      更改爲:
      StudyNo   |   Name   |   Sex   |      Email         |      bouunsNo
      20040901      john         Male       [email protected]           1
      20040902     mary         famale      [email protected]           2
      bounsNo   |   bounsLevel   |   bouns
      1                 優秀                $1000
      2                 良                   $600
      這裏我比較喜歡用bounsNo作爲主鍵,
      基於兩個原因
      1)不要用字符作爲主鍵。可能有人說:如果我的等級一開始就用數值就代替呢?
      2)但是如果等級名稱更改了,不叫 1,2 ,3或優、良,這樣就可以方便更改,所以我一般優先使用與業務無關的字段作爲關鍵字。

      一般滿足前三個範式就可以避免數據冗餘。

      第四範式:
      主要任務:滿足第三範式的前提下,消除多值依賴
      product   | agent | factory
      Car            A1        F1
      Bus           A1         F2
      Car            A2         F2
      在這裏,Car的定位,必須由 agent 和 Factory才能得到(所以主鍵由agent和factory組成),可以通過
      product依賴了agent和factory兩個屬性
      所以正確的是
      表1                              表2:
      product   |   agent            factory |   product
      Car            A1                  F1            Car
      Bus            A1                  F2            Car
      Car            A2                  F2            Bus

      第五範式:
      定義: 如果關係模式R中的每一個連接依賴, 都是由R的候選鍵所蘊含, 稱R是第五範式的
      看到定義,就知道是要消除連接依賴,並且必須保證數據完整
      例子
      A   |   B |   C
      a1      b1   c1
      a2      b1   c2
      a1      b2   c1
      a2      b2   c2
      如果要定位到特定行,必須三個屬性都爲關鍵字。
      所以關係要變爲 三個關係,分別是A 和B,B和C ,C和A
      如下:
      表1          表2         表3
      A   |   B             B   |   C          C    |    A
      a1      b1            b1      c1         c1      a1          
      a1      b2            b1      c2         c1      a2

              
      範式可以避免數據冗餘,減少數據庫的空間,減輕維護數據完整性的麻煩,但是操作難,因爲需要聯繫多個表才能得到所需要數據,而且越高範式性能就會越差。要權衡是否使用更高範式是比較麻煩。
            一般我在做項目中都,用得最多的也就是第三範式,我認爲使用到第三範式也就足夠了,性能好
      而且方便管理數據
      I、關係數據庫設計範式介紹
      1.1 第一範式(1NF)無重複的列
           
      所謂第一範式(1NF)是指數據庫表的每一列都是不可分割的基本數據項,同一列中不能有多個值,即實體中的某個屬性不能有多個值或者不能有重複的屬性。如果出現重複的屬性,就可能需要定義一個新的實體,新的實體由重複的屬性構成,新實體與原實體之間爲一對多關係。在第一範式(1NF)中表的每一行只包含一個實例的信息。簡而言之,第一範式就是無重複的列。
      說明:在任何一個關係數據庫中,第一範式(1NF)是對關係模式的基本要求,不滿足第一範式(1NF)的數據庫就不是關係數據庫。

      1.2 第二範式(2NF)屬性完全依賴於主鍵
           
      第二範式(2NF)是在第一範式(1NF)的基礎上建立起來的,即滿足第二範式(2NF)必須先滿足第一範式(1NF)。第二範式(2NF)要求數據庫表中的每個實例或行必須可以被惟一地區分。爲實現區分通常需要爲表加上一個列,以存儲各個實例的惟一標識。例如員工信息表中加上了員工編號(emp_id)列,因爲每個員工的員工編號是惟一的,因此每個員工可以被惟一區分。這個惟一屬性列被稱爲主關鍵字或主鍵、主碼。

             
      第二範式(2NF)要求實體的屬性完全依賴於主關鍵字。所謂完全依賴是指不能存在僅依賴主關鍵字一部分的屬性,如果存在,那麼這個屬性和主關鍵字的這一部分應該分離出來形成一個新的實體,新實體與原實體之間是一對多的關係。爲實現區分通常需要爲表加上一個列,以存儲各個實例的惟一標識。簡而言之,第二範式就是屬性完全依賴於主鍵。

      1.3 第三範式(3NF)屬性不依賴於其它非主屬性
                 
      滿足第三範式(3NF)必須先滿足第二範式(2NF)。簡而言之,第三範式(3NF)要求一個數據庫表中不包含已在其它表中已包含的非主關鍵字信息。例如,存在一個部門信息表,其中每個部門有部門編號(dept_id)、部門名稱、部門簡介等信息。那麼在的員工信息表中列出部門編號後就不能再將部門名稱、部門簡介等與部門有關的信息再加入員工信息表中。如果不存在部門信息表,則根據第三範式(3NF)也應該構建它,否則就會有大量的數據冗餘。簡而言之,第三範式就是屬性不依賴於其它非主屬性。
      II、範式應用實例剖析
             
      下面以一個學校的學生系統爲例分析說明,這幾個範式的應用。首先第一範式(1NF):數據庫表中的字段都是單一屬性的,不可再分。這個單一屬性由基本類型構成,包括整型、實數、字符型、邏輯型、日期型等。在當前的任何關係數據庫管理系統(DBMS)中,傻瓜也不可能做出不符合第一範式的數據庫,因爲這些DBMS不允許你把數據庫表的一列再分成二列或多列。因此,你想在現有的DBMS中設計出不符合第一範式的數據庫都是不可能的。

      首先我們確定一下要設計的內容包括那些。學號、學生姓名、年齡、性別、課程、課程學分、系別、學科成績,系辦地址、系辦電話等信息。爲了簡單我們暫時只考慮這些字段信息。我們對於這些信息,說關心的問題有如下幾個方面。
      學生有那些基本信息
      學生選了那些課,成績是什麼
      每個課的學分是多少
      學生屬於那個系,系的基本信息是什麼。

      2.1 第二範式(2NF)實例分析
           
      首先我們考慮,把所有這些信息放到一個表中(學號,學生姓名、年齡、性別、課程、課程學分、系別、學科成績,系辦地址、系辦電話)下面存在如下的依賴關係。
              (學號)→ (姓名, 年齡,性別,系別,系辦地址、系辦電話)
               (課程名稱) → (學分)
              (學號,課程)→ (學科成績)
      2.1.1 問題分析
            因此不滿足第二範式的要求,會產生如下問題

              數據冗餘: 同一門課程由n個學生選修,"學分"就重複n-1次;同一個學生選修了m門課程,姓名和年齡就重複了m-1次。
              更新異常:
                   1)若調整了某門課程的學分,數據表中所有行的"學分"值都要更新,否則會出現同一門課程學分不同的情況。
                  2)假設要開設一門新的課程,暫時還沒有人選修。這樣,由於還沒有"學號"關鍵字,課程名稱和學分也無法記錄入數據庫。
             刪除異常 :
      假設一批學生已經完成課程的選修,這些選修記錄就應該從數據庫表中刪除。但是,與此同時,課程名稱和學分信息也被刪除了。很顯然,這也會導致插入異常。
      2.1.2 解決方案
            把選課關係表SelectCourse改爲如下三個表:
      學生:Student(學號,姓名, 年齡,性別,系別,系辦地址、系辦電話);
      課程:Course(課程名稱, 學分);
      選課關係:SelectCourse(學號, 課程名稱, 成績)。
      2.2 第三範式(3NF)實例分析
              接着看上面的學生表Student(學號,姓名,
      年齡,性別,系別,系辦地址、系辦電話),關鍵字爲單一關鍵字"學號",因爲存在如下決定關係:
             (學號)→ (姓名, 年齡,性別,系別,系辦地址、系辦電話)
              但是還存在下面的決定關係
             (學號) → (所在學院)→(學院地點, 學院電話)
              即存在非關鍵字段"學院地點"、"學院電話"對關鍵字段"學號"的傳遞函數依賴。
              它也會存在數據冗餘、更新異常、插入異常和刪除異常的情況。 (數據的更新,刪除異常這裏就不分析了,可以參照2.1.1進行分析)
              根據第三範式把學生關係表分爲如下兩個表就可以滿足第三範式了:
              學生:(學號, 姓名, 年齡, 性別,系別);
              系別:(系別, 系辦地址、系辦電話)。

      總結
             上面的數據庫表就是符合I,II,III範式的,消除了數據冗餘、更新異常、插入異常和刪除異常。
      ====================================================================================================================
      數據庫設計範式深入淺出
      關係數據庫設計之時是要遵守一定的規則的。尤其是數據庫設計範式
      現簡單介紹1NF(第一範式),2NF(第二範式),3NF(第三範式)和BCNF,另有第四範式和第五範式留到以後再介紹。
      在你設計數據庫之時,若能符合這幾個範式,你就是數據庫設計的高手。
      第一範式(1NF):在關係模式R中的每一個具體關係r中,如果每個屬性值
      都是不可再分的最小數據單位,則稱R是第一範式的關係。例:如職工號,姓名,電話號碼組成一個表(一個人可能有一個辦公室電話 和一個家裏電話號碼)
      規範成爲1NF有三種方法:
      一是重複存儲職工號和姓名。這樣,關鍵字只能是電話號碼。
      二是職工號爲關鍵字,電話號碼分爲單位電話和住宅電話兩個屬性
      三是職工號爲關鍵字,但強制每條記錄只能有一個電話號碼。
      以上三個方法,第一種方法最不可取,按實際情況選取後兩種情況。
      第二範式(2NF):如果關係模式R(U,F)中的所有非主屬性都完全依賴於任意一個候選關鍵字,則稱關係R 是屬於第二範式的。
      例:選課關係 SCI(SNO,CNO,GRADE,CREDIT)其中SNO爲學號, CNO爲課程號,GRADEGE 爲成績,CREDIT 爲學分。
      由以上條件,關鍵字爲組合關鍵字(SNO,CNO)
      在應用中使用以上關係模式有以下問題:
      a.數據冗餘,假設同一門課由40個學生選修,學分就 重複40次。
      b.更新異常,若調整了某課程的學分,相應的元組CREDIT值都要更新,有可能會出現同一門課學分不同。
      c.插入異常,如計劃開新課,由於沒人選修,沒有學號關鍵字,只能等有人選修才能把課程和學分存入。
      d.刪除異常,若學生已經結業,從當前數據庫刪除選修記錄。某些門課程新生尚未選修,則此門課程及學分記錄無法保存。
      原因:非關鍵字屬性CREDIT僅函數依賴於CNO,也就是CREDIT部分依賴組合關鍵字(SNO,CNO)而不是完全依賴。
      解決方法:分成兩個關係模式
      SC1(SNO,CNO,GRADE),C2(CNO,CREDIT)。新關係包括兩個關係模式,它們之間通過SC1中的外關鍵字CNO相聯繫,需要時再進行自然聯接,恢復了原來的關係
      第三範式(3NF):如果關係模式R(U,F)中的所有非主屬性對任何候選關鍵字都不存在傳遞信賴,則稱關係R是屬於第三範式的。
      例:如S1(SNO,SNAME,DNO,DNAME,LOCATION) 各屬性分別代表學號,
      姓名,所在系,系名稱,系地址。
      關鍵字SNO決定各個屬性。由於是單個關鍵字,沒有部分依賴的問題,肯定是2NF。但這關係肯定有大量的冗餘,有關學生所在的幾個屬性DNO,DNAME,LOCATION將重複存儲,插入,刪除和修改時也將產生類似以上例的情況。
      原因:關係中存在傳遞依賴造成的。即SNO -> DNO。 而DNO -> SNO卻不存在,DNO -> LOCATION, 因此關鍵遼 SNO 對
      LOCATION 函數決定是通過傳遞依賴 SNO -> LOCATION 實現的。也就是說,SNO不直接決定非主屬性LOCATION。
      解決目地:每個關係模式中不能留有傳遞依賴。
      解決方法:分爲兩個關係 S(SNO,SNAME,DNO),D(DNO,DNAME,LOCATION)
      注意:關係S中不能沒有外關鍵字DNO。否則兩個關係之間失去聯繫。
      BCNF:如果關係模式R(U,F)的所有屬性(包括主屬性和非主屬性)都不傳遞依賴於R的任何候選關鍵字,那麼稱關係R是屬於BCNF的。或是關係模式R,如果每個決定因素都包含關鍵字(而不是被關鍵字所包含),則RCNF的關係模式。
      例:配件管理關係模式 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 丟失了,
      因而對原來的語義有所破壞。沒有體現出每個倉庫裏一種部件由專人負責。有可能出現
      一部件由兩個人或兩個以上的人來同時管理。因此,分解之後的關係模式降低了部分完整性約束。
      一個關係分解成多個關係,要使得分解有意義,起碼的要求是分解後不丟失原來的信息。這些信息不僅包括數據本身,而且包括由函數依賴所表示的數據之間的相互制約。進行分解的目標是達到更高一級的規範化程度,但是分解的同時必須考慮兩個問題:無損聯接性和保持函數依賴。有時往往不可能做到既有無損聯接性,又完全保持函數依賴。需要根據需要進行權衡。

      1NF直到BCNF的四種範式之間有如下關係:
      BCNF包含了3NF包含2NF包含1NF
      小結:
      目地:規範化目的是使結構更合理,消除存儲異常,使數據冗餘儘量小,便於插入、刪除和更新
      原則:遵從概念單一化 "一事一地"原則,即一個關係模式描述一個實體或實體間的一種聯繫。規範的實質就是概念的單一化。
      方法:將關係模式投影分解成兩個或兩個以上的關係模式。
      要求:分解後的關係模式集合應當與原關係模式"等價",即經過自然聯接可以恢復原關係而不丟失信息,並保持屬性間合理的聯繫。

      注意:一個關係模式結這分解可以得到不同關係模式集合,也就是說分解方法不是唯一的。最小冗餘的要求必須以分解後的數據庫能夠表達原來數據庫所有信息爲前提來實現。其根本目標是節省存儲空間,避免數據不一致性,提高對關係的操作效率,同時滿足應用需求。實際上,並不一定要求全部模式都達到BCNF不可。有時故意保留部分冗餘可能更方便數據查詢。尤其對於那些更新頻度不高,查詢頻度極高的數據庫系統更是如此。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章