如何理解關係模式三範式?
什麼是範式?
簡單的說,範式是為了消除重複數據減少冗餘數據,從而讓資料庫內的數據更好的組織,讓磁碟空間得到更有效利用的一種標準化標準,滿足高等級的範式的先決條件是滿足低等級範式。(比如滿足2nf一定滿足1nf)
我們為什麼需要範式?
關係資料庫的設計主要是關係模式的設計,關係模式設計的好壞將直接影響到資料庫設計的性能。將關係模式規範化是至關重要的。接下來我將從第一範式到BC範式,逐個講起每個範式的意義及其作用以及他避免的問題。
第一範式
第一範式是關係模式要遵循的基本範式。其定義為:
在關係模式R中,其所有屬性均為簡單屬性,即每個屬性都是不可再分的,那麼則稱R為第一範式
第一範式的定義十分容易理解,也十分容易做到。當我們要求關係模式為第一範式時,只需要在定義屬性時做到簡單屬性即可。反之而言,如果一個關係模式不是第一範式,那麼其存在某個或者某些屬性組是由幾個簡單屬性組合而成,那麼關係模式就會轉變為多層次的混合結構。這將很大程度的增加關係操作的複雜性。所以在關係資料庫中第一範式是必須要滿足的。
然而第一範式只是關係模式範式中最基礎的一個模式,其本身依舊存在許多致命的問題。如數據冗餘,插入刪除更新的異常。
舉個例子:
假設關係模式R為:
(學生ID,姓名,課程號,課程名,所在系,系主任,成績)
數據冗餘
可以得出這個關係模式屬於第一模式。然而這樣的關係模式什麼問題呢?比如從數據冗餘角度來說,我們有理工大類學生A,選了數學與英語課。那麼在關係模式中則會存有兩個欄位:
(A_Id,A,課程號1,數學,理工大類,AAA,1.0)
(A_ID, A,課程號2,英語,理工大類,AAA,1.0)
從這我們可以看出,除了課程的相關屬性,其他屬性完全一樣,純粹是再存入了一遍,這明顯造成了數據冗餘。
插入異常
那麼現在來一個轉學生B,轉學生初來乍到還沒有選課,但是學生信息必須先錄入那該怎麼辦呢?我們會發現我們遭遇了這樣的窘狀:
(B_ID,B,NULL,NULL,理工大類,AAA,NULL)
當我們在錄入課程號和課程名的時候,完全無法填寫,那麼我們就無法插入新的記錄。造成了插入異常。
刪除異常
那麼現在假設我們的B同學終於選了一門語文課,錄入資料庫以後突然覺得自己更喜歡數學課,於是出現了下面這一幕:
B:老師老師!我要改課,我想把我的語文課退了改成數學課!
老師:好的等一下我先把你的語文課記錄刪去....OK,搞定,現在給你登入數學課的記錄,額..你學號是多少?
B:啊?學號?我忘了!!(小B剛來學校,還沒完全記住學號) 直接在資料庫里找我的學號不就好了
老師:啊可是我剛剛刪掉了你的記錄...
我們發現,剛剛老師在刪除小B選的語文課記錄時,這個關係模式中同樣包含了小B的姓名學號等其他信息,當我們刪除這條記錄以後,可能會給我們帶來其他數據的損失,這就是刪除異常。
更新異常
小A是一個很矯情的小婊砸,有一天他突然覺得自己的名字不好聽,去民政局把自己的名字改成了Accepted.一下子高大上了有沒有!
於是理所當然的小Accepted跑去了資料庫老師那更新信息,然後資料庫老師便找到了
(A_Id,學生A,課程號1,數學,理工大類,AAA)
這條欄位,很瀟洒的把記錄更改為
(A_Id, Accpted,課程號1,數學,理工大類,AAA)
心想這下肯定不會出差錯了吧。然而細心的我們其實早就意識到,關於小A的記錄並非只有一條,老師雖然將這條記錄更改了,但是資料庫中還存在著另外一條記錄
(A_Id,學生A,課程號1,數學,理工大類,AAA)
這便是更新異常
事實上,這三種異常的情況有很多種,我所用的例子是最常見的異常情況,藉此幫助我們理解第一範式在進行增查刪改時所會遇到的異常理解。
對於第一範式所遇到的問題,我們要將其修改為第二範式,但是首先我們在改變為第二範式前,我們必須先引入一種名為函數依賴的關係:
對於關係模式R<U>,U為屬性全集,X,Y分別為U的子集,
對於R<U>的任意一個記錄r來說,每個X只能確定一個唯一的Y。
記作X-->Y,稱為X確定Y,或者Y依賴X。
這個關係十分像我們初中時學習的函數y=f(x),每個x確定一個y,當然也可以多個X對應一個Y,即是多對一的關係。
值得注意的是: 我們在本文中大多數情況的是非平凡的函數依賴關係,即X不包含Y。反之,X包含Y的函數依賴稱為平凡的函數依賴。
完全依賴,部分依賴
還是以關係模式R為例,我們發現之所以處於第一範式的R會有如此多的異常問題,究極根本原因是其中的屬性值存在各種各樣的函數依賴關係。
對於關係模式R,我們容易得出他的碼為(學生ID,課程號ID),那麼也就是說對於任何一個給定的碼的記錄而言,我們都可以通過這些信息得到這條記錄的其他屬性值信息。但是細心的同學會發現,對於某些屬性值,我們只需要碼的子集便可得出:
比如對於關係模式R(學生ID,姓名,課程號,課程名,所在系,系主任,成績)
我們發現當我們需要得知學生姓名時,只需要學生ID即可。
同理我們需要課程名的時候只需要課程ID即可,而不需要整個碼。
如果說對於屬性組X,X-->Y,並且X的子集X也同樣決定了Y,即X『-->Y。我們將其稱為Y對X的部分函數依賴,記作X-P->Y
反之,如果不存在X的子集X』可以決定Y,並且X-->Y,那麼我們將其稱之為完全函數依賴,記作:X-F->Y
第二範式
當我們搞明白了部分函數依賴於完全函數依賴時,就可以很輕鬆的明白什麼是第二範式。所謂的第二範式,就是指對於關係R屬於第一範式,同時R的每個非主屬性完全依賴於碼,那麼我們將其稱之為第二範式。
從剛剛的關係模式R中,我們可以得到:
學號ID-P->姓名 課程號ID-P->課程名 (學號ID,課程號ID)-F->成績
其他不寫了...
所以從函數依賴關係上,我們可以將原來的表分為
R0(學生號,學生名,所在系,系主任)R1(學生號,課程號,成績)R2 (課程號,課程名)
現在看起來比一開始順眼多了。雖然依舊存在問題 _(:зゝ∠)\_
第三模式
假設學生B覺得理工大類讀的好枯燥,一怒之下轉到了經管大類開始了新生活,於是我們將他的信息更改為
(B_ID,B,經管大類,AAA)
這裡我們就瞬間發現問題啦,問題在於雖然小B的所在系更改了,但是從現實的角度考慮小B的系主任不應該是原來的系主任啊? 但是為什麼這個問題我們會一開始沒有發現呢?原來雖然所在系與系主任對於關係R0的碼來說都是完全依賴,但是從現實因素考慮,所在系依舊可以決定了這個系主任 即所在系-->系主任,我們發現這其中
學生號-->所在系, 所在系-->系主任
也就是說對於非主屬性Z而言 ,存在屬性組Y,使得X-->Y,Y-->Z。我們將其稱之為Z對X的傳遞依賴。
而第三模式就是在第二模式的基礎上去除傳遞依賴。也就是說我們只要在原來的基礎上如此修改:
R0(學生號,學生名,所在系)R1(所在系,系主任)R2(學生號,課程號,成績)R3 (課程號,課程名)
便已經修改為第三範式了。而第三範式也在現實層面的應用中最為廣泛。
BC範式
BC範式是第三範式的加強版,他強調了關係模式R中所有的屬性(包括主屬性和非主屬性)都完全依賴於碼或候選鍵,並且不存在傳遞依賴的情況。
從定義上我們可以看出,如果說第二範式是消除了非主屬性對主屬性的部分依賴,第三範式消除了非主屬性對主屬性的傳遞依賴,那麼BC範式則是對所有屬性消除了對於主屬性的傳遞依賴與部分依賴。換句話說,在第三範式的基礎上,他消除了主屬性之間的傳遞依賴與部分依賴。
推薦閱讀:
※雲資料庫UDB的三重境界
※手把手教您解決90%的自然語言處理問題
※深入淺出hbase和bigtable
※簡析關係型資料庫和非關係型資料庫的比較(下)
※資料庫管理系統(一): 並發控制簡介