最簡單的數據庫“範式”教程

版權聲明:轉載自  鏈接  https://blog.csdn.net/yangbodong22011/article/details/51619590 

既然都叫最簡單的數據庫“範式”教程,我覺得它一定要滿足這個要求:看完這篇博客,你一定會明白數據庫的“範式”和那些諸如“完全函數依賴”,“部分函數依賴”,“傳遞函數依賴”等煩人的概念,前提是你得跟着我的思路認真的讀完它,好,準備好你的半個小時了嗎?我們開始。

目錄

  1. 什麼是範式?
  2. 貫穿全文的一個例子。
  3. 第一範式(1NF)
  4. 幾個重要的概念。
  5. 第二範式(2NF)
  6. 第三範式(3NF)
  7. BC範式(BCNF)
  8. 第四範式(4NF)

1. 什麼是範式?

範式其實就是關係數據庫規範程度的級別,舉個我們生活中的例子,老師讓打掃衛生,最低標準是掃地,二級標準是掃地+擦桌子,三級標準是掃地+擦桌子+擦玻璃,實際上在標準不斷上升的過程中,首先高一級的標準是滿足低一級標準的,範式也是如此,只不過它的標準描述的是數據庫規範化的程度罷了。數據庫中的範式有1NF , 2NF , 3NF , BCNF , 4NF,5NF(本文不討論)。它們之間的關係1NF < 2NF < 3NF < BCNF < 4NF(默認越大 級別越高)。

2.貫穿全文的一個例子。

這裏寫圖片描述
這個例子有下面的關係

(學號,課名)->分數
學號->姓名
學號->系名
系名->系主任
注:A->B:理解爲A屬性可以唯一確定B屬性。

這個例子會在說第二範式和第三範式的時候被逐步優化。

3.第一範式(1NF)

數據庫表的每一列都是不可再分的原子數據項,它是一個關係型數據庫的最低標準,如果不滿足第一範式,那麼這個數據庫就不是關係型數據庫。如下所示:
這裏寫圖片描述
這個表我們無法在數據庫中直接創建,因爲它的這一列,既有系名又有系主任,產生了衝突,如果作出調整,使它符合第一範式,那麼應該是這樣的:
這裏寫圖片描述

但是即使這樣,數據庫中還是會存在諸如插入、刪除、數據冗餘等異常。比如針對下面的表:
這裏寫圖片描述

  • 數據冗餘:可以看到姓名、系名和系主任這三列冗餘非常大。
  • 插入異常:如果目前開設了計算機系,但是尚未招生,那麼計算機系是無法插入到表的系名中的,(學號,課名)是主屬性,不能爲空。
  • 刪除異常:如果經濟系的學生全部畢業了,在刪除所有學生的時候,會將經濟系一併刪除

因此這個數據庫的設計是有缺陷的,爲了優化它,我們繼續到第二範式。在說第二範式之前,我們先來說幾個重要的概念。

4.幾個重要的概念。

  • 函數依賴:在一張表中,如果給定A屬性(或屬性組)的值,一定能唯一確定B屬性的值,那麼就說B依賴於A屬性(或屬性組),記作A->B,比如給定學號,就能確定姓名,一個學號一定能確定一個姓名,就這麼簡單,是不是似曾相識?對,我們在第二部分中說那個貫穿全文的例子的時候其實已經用到這個概念了。

  • 完全函數依賴:在函數依賴的基礎上,我們的A屬性是一個屬性組,只有這個屬性組中的全部屬性才能確定唯一的B屬性,A的任何一個子集都不可以。比如(學號,課名)->成績,而單獨的學號或者課名都不能確定成績,這就叫完全函數依賴。

  • 部分函數依賴:和完全函數依賴相比,A屬性組中的部分屬性就能確定B屬性,其它屬性可有可無,比如(學號,課名)->姓名,其實只要學號就可以了,這樣的依賴就叫部分函數依賴。

  • 傳遞函數依賴:如果A->B,B->C,並且B不能->A(防止直接A->C),那麼我們可以得出結論A->C,叫做C傳遞函數依賴A。比如學號->系名,系名->系主任,並且(系名不能決定學號),所以系主任傳遞函數依賴學號。

  • 碼:一個屬性或者屬性組,使得整個關係中除過此屬性或者屬性組之外的其餘屬性都完全函數依賴於它,那它就是碼。例如(學號,成績),它們兩個的組合可以將其他所有的屬性都決定了,(學號,課名)->分數,學號->姓名,學號->系名,學號->系名->系主任,所以(學號,課名)就是這個關係中的一個碼,那這個關係中還有別的碼嗎? 誰知道呢,但我們的分析過程應該是這樣的:從一個屬性一直到n個屬性全部來一遍。

    1. 一個屬性:學號,姓名,系名,系主任,課名,分數。找反例即可:學號不能決定分數,(必須要課名),姓名什麼也決定不了,系名只能決定系主任,課名也決定不了什麼,分數一樣。所以一個屬性中肯定是沒有碼的。
    2. 兩個屬性:(學號,姓名),(學號,系名),(學號,系主任),(學號,課名),(學號,分數),(姓名,系名),(姓名,系主任),(姓名,課名),(姓名,分數),(系名,系主任),(系名,課名),(系名,分數),(系主任,課名),(系主任,分數),(課名,分數)。呼~終於完了,我們再進行分析,發現只有(學號,課名),這個組合與其他的關係來說是完全函數依賴。也就是它們是一個碼。
    3. 三個屬性:……
    4. 四個屬性:……
    5. 五個屬性:……
    6. 六個屬性:……

好吧,只能這樣嗎?對,只能這樣這裏寫圖片描述,其實有一些能減少工作量的方法,比如如果我們在分析兩個屬性時已經確定(學號,課名)是,那麼在以後的分析中,如果包含(學號,課名)的那就一定不是碼,因爲要完全函數依賴。比如(學號,課名,系名)就不用分析了。其他的方法大家自己總結吧。

  • 主屬性:所有的碼中包含的屬性都是主屬性。
  • 非主屬性:除過碼中包含屬性之外的屬性。

呼呼~,返過頭再看一遍,我們要向第二範式出發了。

5. 第二範式(2NF)

在第一範式基礎上,消除非主屬性對主屬性的部分函數依賴,針對我們的例子,分析如下:
主屬性:學號,課名
非主屬性:姓名,系名,系主任,分數

目前只有一張表:
(學號,姓名,系名,系主任,課名,分數)

明顯,姓名和系名都是對(學號,課名)存在部分函數依賴的。因爲其實只需要學號就可以決定姓名和系名。所以這個表目前是不符合第二範式的,我們只好對錶作出分解,當然分解的模式不是唯一的,下面只是一種情況,如下所示:

選課(學號,課名,分數)
學生(學號,姓名,系名,系主任)
這裏寫圖片描述
我們此時再來看兩張表是否滿足第二範式:
選課表:主屬性:(學號,課名)。非主屬性:分數。 不存在非主屬性對主屬性的部分函數依賴,滿足第二範式。
學生表:主屬性:學號。非主屬性:系名,系主任,姓名。因爲主屬性只有一個,所以一定不存在非主屬性對主屬性的部分函數依賴。滿足第二範式。

至於怎麼找主屬性,不用我強調了吧,要是忘了的話回頭看看上面。此時數據變成了這樣:
這裏寫圖片描述

我們回頭看看前面的問題有沒有得到改善:

  • 數據冗餘問題:姓名、系名、系主任的數據冗餘得到了明顯改善。
  • 插入異常問題:現在新開設一個系,尚未招生還是無法將系名插入到學生表中,因爲學號是主屬性,不能爲空。沒有改善。
  • 刪除異常問題:一個系畢業,刪除這個系的所有學生信息,那還是會連帶刪除掉系的信息。沒有改善。

因此,只滿足第二範式也還是不夠。還是存在好多問題。

6. 第三範式(3NF)

在第二範式基礎上,消除非主屬性對主屬性的傳遞函數依賴,同樣,我們繼續分析我們的例子:
主屬性:學號,課名
非主屬性:姓名,系名,系主任,分數

目前我們的表如下:
選課(學號,課名,分數)
學生(學號,姓名,系名,系主任)

我們發現在學生表中:存在非主屬性系主任對主屬性學號的傳遞函數依賴。因爲學號->系名,系名->系主任,所以纔會出現前面那麼多的問題。那我們試着再次分解學生表,消除這種傳遞函數依賴。分解後如下:

選課(學號,課名,分數)
學生(學號,姓名,系名)
系(系名,系主任)
這裏寫圖片描述

我們繼續分析:
選課表中碼爲(學號,課名),非主屬性爲分數,它們是完全函數依賴的關係,不存在非主屬性對主屬性的傳遞函數依賴。符合第三範式。
對於學生表,碼爲學號,主屬性爲學號,非主屬性爲系名,不可能存在非主屬性對於碼的傳遞函數依賴,符合第三範式,
對於系表,碼爲系名,主屬性爲系名,非主屬性爲系主任,不可能存在非主屬性對於碼的傳遞函數依賴(至少要有三個屬性纔可能存在傳遞函數依賴關係),也符合第三範式。

此時數據成了現在這樣:
這裏寫圖片描述

我們再回頭看看前面的問題有沒有得到改善:

  • 插入異常問題:現在新開設一個系,尚未招生我們卻可以保存系的信息,因爲我們有系這個表。問題得到改善。
  • 刪除異常問題:一個系畢業,刪除這個系的所有學生信息,現在不會連帶刪除掉系的信息,因爲我們有系這個表。問題得到改善。

當數據庫到達第三範式的時候,基本上有關數據冗餘,數據插入、刪除、更新的異常問題得到了解決,這也是一個”合法的”數據庫最基本的要求,但是效率問題就另當別論了,因爲表越多,連接操作就越多,但是連接是一個比較耗資源的操作。對於我們前面的例子,已經優化到最好了,也沒有再次優化的地方。下面我們說到BC範式的時候會說另一個例子。

7. BC範式(BCNF)

在第三範式基礎上,消除主屬性對主屬性的部分函數依賴與傳遞函數依賴,什麼?沒搞錯吧?對,沒搞錯。我們看下面的例子。
若:
1:某公司有若干個倉庫;
2:每個倉庫只能有一名管理員,一名管理員只能在一個倉庫中工作;
3:一個倉庫中可以存放多種物品,一種物品也可以存放在不同的倉庫中。每種物品在每個倉庫中都有對應的數量。

如下所示:
這裏寫圖片描述

屬性有:倉庫,管理員,物品,數量。
我們先來找碼:

  • 一個屬性:沒有
  • 二個屬性:(管理員,物品),(倉庫,物品)
  • 三個屬性:包含兩個屬性中的了,pass
  • 四個屬性:包含兩個屬性中的了,pass

我們得到主屬性:管理員,物品,倉庫
非主屬性:數量

不存在數量對主屬性的部分函數依賴和傳遞函數依賴,有的人可能有疑問?明明(倉庫,物品)->數量,爲什麼不是部分函數依賴,是因爲我們這裏說的主屬性是碼,此時的三個主屬性是由兩個碼(管理員,物品),(倉庫,物品)合起來組成的,它們之間任何一個和數量都不能部分函數依賴。因此這個表是滿子第三範式的,但是它還是存在下面的問題:

  • 刪除問題:對於最後一條記錄,(北京倉,李四,iPad Mini,60),我們以後再也不會往這個倉庫中存iPad Mini 了,那刪除的時候只能連同倉庫一起刪除。
  • 插入問題:如果新建倉庫,尚未存入物品,那麼也不能爲倉庫分配管理員。
  • 修改異常:如果某個倉庫更換了管理員,修改的時候需要逐條記錄一起修改。

既然都滿足第三範式了,那爲什麼還是會出現這麼多的問題呢?因爲存在主屬性對主屬性的部分函數依賴,此例子中存在(管理員,物品名)->倉庫,但是實際上管理員->倉庫。因此就存在了主屬性對主屬性(碼)的部分函數依賴。

我們將其模式分解:
倉庫(倉庫名,管理員)
庫存(倉庫名,物品名,數量)

再次回頭看與原來的問題有沒有得到解決

  • 刪除問題:因爲倉庫現在有專門的表,所以刪除物品的時候不會影響倉庫。問題得到改善。
  • 插入問題:現在直接再倉庫表中新建倉庫,與管理員沒有關係。得到改善。
  • 修改異常:修改了某個倉庫的管理員,直接修改倉庫表就可以了。得到改善。

符合BCNF的數據庫已經非常嚴格了。但是這種嚴格只是在函數依賴層面的。啥?上升層面?不是吧,對!接下來要說的第四範式研究的領域是多值依賴層面的。

8. 第四範式(4NF)

那我們還是開門見山的來看一個例子:

Teaching(C,T,B),C表示課程,T表示老師,B表示參考書。
有下面未規範化的關係:
這裏寫圖片描述

我們先讓它滿足1NF如下所示:
這裏寫圖片描述

發現存在許多問題:

  • 信息冗餘:課程和教師存在大量的數據冗餘。
  • 插入問題:當某個課程增加了一個任課老師,那麼需要插入多個元組。
  • 刪除問題:如果刪除一本書,需要刪除很多條記錄,非常麻煩。

我們再來看它到底屬於第幾範式。發現這個關係中C、T、B都是唯一的,也就是全鍵。不存在非主屬性,也不存在主屬性對主屬性的的部分函數依賴和傳遞函數依賴(因爲那樣碼中至少要兩個主屬性),它只有一個碼(C、T、B)。也就是這個關係是屬於BCNF的。那它又爲什麼會出現這麼多問題呢?就是因爲它存在多值依賴。

多值依賴:在關係模式R(U)中,X、Y、Z是U的子集,Z=U-X-Y。如果多值依賴X->->Z成立,那麼給定(x,y),能確定z的一組值,而且這個值僅由x決定,與y沒有關係。

比如:在Teaching中,C、B、T是Teaching的子集,T=Teaching-C-B。給定(C,B),比如(數據庫原理與應用,SQL Server 2000),能確定一組T值(鄧宇,孫澤)。但是這組T值只與C(數據庫原理與應用)有關,與B(SQL Server 2000)沒有關係,我們就說C->->T。叫做T多值依賴於C。

平凡多值依賴:如果y爲空集。X->->Z就是平凡多值依賴
非平凡多值依賴:y不爲空。

其實已經分析完了,就是因爲Teaching關係中存在多值依賴,所以纔會由我們說的問題,我們進行模式分解,分解得到的表如下所示:

TC表(課程,教師)
BC表(課程,參考書)

看看我們的問題有沒有得到解決:

  • 信息冗餘:得到改善。
  • 插入問題:某個課程增加老師,只要在TC表中添加一條記錄就好了。改善
  • 刪除問題:刪除一本書,也只要在BC表中刪除一條記錄即可。改善

現在的表是滿足第四範式的,說了這麼多,我們最後給出第四範式的定義:關係模式R滿足1NF的前提下,如果R中每一個非平凡多值依賴X->->Y,X中都含有鍵,則R屬於4NF,前面討論的關係中。鍵是(T、C、B),是全鍵。C->->B,C->->T,這種多值依賴是非平凡的,但是單獨的C不是鍵,所以就無法滿足第四範式。

總結 :函數依賴和多值依賴是兩種重要的數據依賴。如果只考慮函數依賴,BCNF已經是非常高的級別了,而且再往上考慮除了多值依賴還有連接依賴,連接依賴屬於5NF的範疇了。通過本文中的三個不同例子也能看出來,數據庫優化針對不同的數據庫到達相應的級別就好,簡單的數據庫到達第三範式就已經非常完美了。而且增加範式就意味着分解,分解意味着以後可能會連接查詢,那樣又會影響效率。最後給出著名的數據庫優化十六字經:由低到高,逐步規範,權衡利弊,適可而止這裏寫圖片描述

如果認真的看到這裏,我想你一定有所收穫,那麼贊一個吧。

參考資料:劉慰老師

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