書上講了好多, 歸結起來3句話:
1NF:字段不可分;
2NF:有主鍵,非主鍵字段依賴主鍵;
3NF:非主鍵字段不能相互依賴;
解釋: 1NF:原子性 字段不可再分,否則就不是關係數據庫; 2NF:唯一性 一個表只說明一個事物; 3NF:每列都與主鍵有直接關係,不存在傳遞依賴; 不符合第一範式的例子(關係數據庫中create不出這樣的表): 表:字段1, 字段2(字段2.1, 字段2.2), 字段3 ...... 存在的問題: 因爲設計不出這樣的表, 所以沒有問題; 不符合第二範式的例子: 表:學號, 姓名, 年齡, 課程名稱, 成績, 學分; 這個表明顯說明了兩個事務:學生信息, 課程信息; 存在問題: 數據冗餘,每條記錄都含有相同信息; 刪除異常:刪除所有學生成績,就把課程信息全刪除了; 插入異常:學生未選課,無法記錄進數據庫; 更新異常:調整課程學分,所有行都調整。 修正: 學生:Student(學號, 姓名, 年齡); 課程:Course(課程名稱, 學分); 選課關係:SelectCourse(學號, 課程名稱, 成績)。 滿足第2範式只消除了插入異常。 不符合第三範式的例子: 學號, 姓名, 年齡, 所在學院, 學院聯繫電話,關鍵字爲單一關鍵字"學號"; 存在依賴傳遞: (學號) → (所在學院) → (學院地點, 學院電話) 存在問題: 數據冗餘:有重複值; 更新異常:有重複的冗餘信息,修改時需要同時修改多條記錄,否則會出現數據不一致的情況 刪除異常 修正: 學生:(學號, 姓名, 年齡, 所在學院); 學院:(學院, 地點, 電話)。
第一範式(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.第三範式(確保每列都和主鍵列直接相關,而不是間接相關)
第三範式需要確保數據表中的每一列數據都和主鍵直接相關,而不能間接相關。
比如在設計一個訂單數據表的時候,可以將客戶編號作爲一個外鍵和訂單表建立相應的關係。而不可以在訂單表中添加關於客戶其它信息(比如姓名、所屬公司等)的字段。如下面這兩個表所示的設計就是一個滿足第三範式的數據庫表。
這樣在查詢訂單信息的時候,就可以使用客戶編號來引用客戶信息表中的記錄,也不必在訂單信息表中多次輸入客戶信息的內容,減小了數據冗餘。
以上就是數據庫三大範式的介紹,希望對大家設計冗餘較小、結構合理的數據庫有所幫助。