三範式歸類學習

書上講了好多, 歸結起來3句話: 


1NF:字段不可分; 

2NF:有主鍵,非主鍵字段依賴主鍵; 

3NF:非主鍵字段不能相互依賴; 

解釋: 1NF:原子性 字段不可再分,否則就不是關係數據庫; 2NF:唯一性 一個表只說明一個事物; 3NF:每列都與主鍵有直接關係,不存在傳遞依賴; 不符合第一範式的例子(關係數據庫中create不出這樣的表): 表:字段1, 字段2(字段2.1, 字段2.2), 字段3 ...... 存在的問題: 因爲設計不出這樣的表, 所以沒有問題; 不符合第二範式的例子: 表:學號, 姓名, 年齡, 課程名稱, 成績, 學分; 這個表明顯說明了兩個事務:學生信息, 課程信息; 存在問題: 數據冗餘,每條記錄都含有相同信息; 刪除異常:刪除所有學生成績,就把課程信息全刪除了; 插入異常:學生未選課,無法記錄進數據庫; 更新異常:調整課程學分,所有行都調整。 修正: 學生:Student(學號, 姓名, 年齡); 課程:Course(課程名稱, 學分); 選課關係:SelectCourse(學號, 課程名稱, 成績)。 滿足第2範式只消除了插入異常。 不符合第三範式的例子: 學號, 姓名, 年齡, 所在學院, 學院聯繫電話,關鍵字爲單一關鍵字"學號"; 存在依賴傳遞: (學號) → (所在學院) → (學院地點, 學院電話) 存在問題: 數據冗餘:有重複值; 更新異常:有重複的冗餘信息,修改時需要同時修改多條記錄,否則會出現數據不一致的情況 刪除異常 修正: 學生:(學號, 姓名, 年齡, 所在學院); 學院:(學院, 地點, 電話)。 




 SQL三大範式三個例子搞定 

第一範式(1NF)

(必須有主鍵,列不可分)

數據庫表中的何字段都是單一屬性的,不可再分

create table aa(id int,NameAge varchar(100)) 
insert aa values(1,''無限-女'') 
沒有達到第一範式 

create table aa(id int,name varcahr(10),age char(2)) 
insert aa values(1,''無限'',''女'') 
達到第一範式

第二範式(2NF)

數據庫表中非關鍵字段對一候選關鍵字段的 都不存在部分函數依賴

(當一個表是複合主鍵時,非主鍵的字段不依賴於部分主鍵(即必須依賴於全部的主鍵字段))

create table sci(

   sno int(32),cno int(32),grade int(32),credit int(32),

primary key sno,cno

)

課程(cno)1---1學分(credit)

學生(sno)n---n課程(cno)

學生+課程--->分數(grade)

sci

sno cno grade credit

1    1   60     80

2    1    90     80

3   1    70     80

.   .   .      .

.   .   .     .

.    .   .     .

如此以來,學分被大量重複存儲,數據冗餘

如要某課程學分,則要大量重複操作

如要加新課程,由於sno和cno共同做爲主鍵,則在加入新課程時,必須有人選該課

如某學生某課程結業,則該學生其它課程信息也同時被刪除了

總之

這種設計不太好吧,非關鍵字屬性credit僅函數依賴於cno,也就是credit部分依賴組合關鍵字(sno,cno)而不是完全依賴

解決

分成兩個關係模式 sc1(sno,cno,grade),c2(cno,credit)。新關係包括兩個關係模式,它們之間通過sc1中的外關鍵字cno相聯繫,需要時再進行自然聯接,恢復了原來的關係

第三範式(3NF)

關係模式R(U,F)中的所有非主屬性對何候選關鍵字都不存在傳遞依賴

例----S1(SNO,SNAME,DNO,   DNAME, LOCATION)

          學號 姓名   所在系 系名稱 系地址 
關鍵字SNO決定各個屬性。由於是單個關鍵字,沒有部分依賴的問題,肯定是2NF。但這關係肯定有大量的冗餘,有關學生所在的幾個屬性DNO,DNAME,LOCATION將重複存儲,插入,刪除和修改時也將產生類似以上例的情況。 
原因:關係中存在傳遞依賴造成的。即SNO 1->1 DNO。 而DNO 1->n SNO卻不存在,而DNO -> LOCATION存在, 因此關鍵遼 SNO 對 LOCATION 函數決定是通過傳遞依賴 SNO -> LOCATION 實現的。也就是說,SNO不直接決定非主屬性LOCATION。 
解決目地:每個關係模式中不能留有傳遞依賴。 
解決方法:分爲兩個關係 S(SNO,SNAME,DNO),D(DNO,DNAME,LOCATION) 
注意:關係S中不能沒有外關鍵字DNO。否則兩個關係之間失去聯繫

鮑依斯-科得範式(BCNF)

在3NF的基礎上,庫表中何字段對一候選關鍵字段的傳遞函數依賴都不存在

倉庫管理關係表爲StorehouseManage(倉庫ID, 存儲物品ID, 管理員ID, 數量),且管理員1---1倉庫;倉庫1---n物品。這個數據庫表中存在如下決定關係:
  (倉庫ID, 存儲物品ID) →(管理員ID, 數量)
(管理員ID, 存儲物品ID) → (倉庫ID, 數量)
所以,(倉庫ID, 存儲物品ID)和(管理員ID, 存儲物品ID)都是StorehouseManage的候選關鍵字,表中的唯一非關鍵字段爲數量,它是符合第三範式的。但是,由於存在如下決定關係:
(倉庫ID) → (管理員ID)
(管理員ID) → (倉庫ID)
即存在關鍵字段決定關鍵字段的情況,所以其不符合BCNF範式

解決:

把倉庫管理關係表分解爲二個關係表:
  倉庫管理:StorehouseManage(倉庫ID, 管理員ID)

倉庫:Storehouse(倉庫ID, 存儲物品ID, 數量)

數據庫設計三大範式簡析

這篇文章主要介紹了數據庫設計三大範式簡析,遵循範式是爲了建立冗餘較小、結構合理的數據庫,需要學習數據庫設計三大範式的朋友可以參考下

爲了建立冗餘較小、結構合理的數據庫,設計數據庫時必須遵循一定的規則。在關係型數據庫中這種規則就稱爲範式。範式是符合某一種設計要求的總結。要想設計一個結構合理的關係型數據庫,必須滿足一定的範式。       
在實際開發中最爲常見的設計範式有三個:

1.第一範式(確保每列保持原子性)

第一範式是最基本的範式。如果數據庫表中的所有字段值都是不可分解的原子值,就說明該數據庫表滿足了第一範式。

第一範式的合理遵循需要根據系統的實際需求來定。比如某些數據庫系統中需要用到“地址”這個屬性,本來直接將“地址”屬性設計成一個數據庫表的字段就行。但是如果系統經常會訪問“地址”屬性中的“城市”部分,那麼就非要將“地址”這個屬性重新拆分爲省份、城市、詳細地址等多個部分進行存儲,這樣在對地址中某一部分操作的時候將非常方便。這樣設計纔算滿足了數據庫的第一範式,如下表所示。

上表所示的用戶信息遵循了第一範式的要求,這樣在對用戶使用城市進行分類的時候就非常方便,也提高了數據庫的性能。

               

2.第二範式(確保表中的每列都和主鍵相關)

第二範式在第一範式的基礎之上更進一層。第二範式需要確保數據庫表中的每一列都和主鍵相關,而不能只與主鍵的某一部分相關(主要針對聯合主鍵而言)。也就是說在一個數據庫表中,一個表中只能保存一種數據,不可以把多種數據保存在同一張數據庫表中。

比如要設計一個訂單信息表,因爲訂單中可能會有多種商品,所以要將訂單編號和商品編號作爲數據庫表的聯合主鍵,如下表所示。

 訂單信息表

這樣就產生一個問題:這個表中是以訂單編號和商品編號作爲聯合主鍵。這樣在該表中商品名稱、單位、商品價格等信息不與該表的主鍵相關,而僅僅是與商品編號相關。所以在這裏違反了第二範式的設計原則。

而如果把這個訂單信息表進行拆分,把商品信息分離到另一個表中,把訂單項目表也分離到另一個表中,就非常完美了。如下所示。

這樣設計,在很大程度上減小了數據庫的冗餘。如果要獲取訂單的商品信息,使用商品編號到商品信息表中查詢即可。

3.第三範式(確保每列都和主鍵列直接相關,而不是間接相關)

第三範式需要確保數據表中的每一列數據都和主鍵直接相關,而不能間接相關。

比如在設計一個訂單數據表的時候,可以將客戶編號作爲一個外鍵和訂單表建立相應的關係。而不可以在訂單表中添加關於客戶其它信息(比如姓名、所屬公司等)的字段。如下面這兩個表所示的設計就是一個滿足第三範式的數據庫表。

這樣在查詢訂單信息的時候,就可以使用客戶編號來引用客戶信息表中的記錄,也不必在訂單信息表中多次輸入客戶信息的內容,減小了數據冗餘。

以上就是數據庫三大範式的介紹,希望對大家設計冗餘較小、結構合理的數據庫有所幫助。


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