數(shù)據(jù)庫(3)---更新異常與規(guī)范化設(shè)計(jì)

【聲明】本文章來自穆晨 - 博客園,記錄于此方便后期的學(xué)習(xí)和查閱

一、前言

在前兩篇中,主要講了ER建模和關(guān)系建模。在具體分析如何用數(shù)據(jù)庫管理軟件RDBMS(Relational Database Management System)實(shí)現(xiàn)這些關(guān)系前,先思考下面的問題

為什么要這么麻煩?為什么又是ER建模又是關(guān)系建模的?

本篇的出發(fā)點(diǎn)就是回答這個(gè)問題。某種程度上,也是回答另一個(gè)本質(zhì)性的問題:為什么要有數(shù)據(jù)庫?

二、更新異常

數(shù)據(jù)庫的四大操作:增,刪,改,查中,除了查,其他三個(gè)都可歸為更新操作。

總的來說,ER建模和關(guān)系建模的目的,就是為了避免因大量冗余數(shù)據(jù)導(dǎo)致的數(shù)據(jù)庫更新異常。

本文將使用一張旅游公司的數(shù)據(jù)表,來具體分析沒有ER建模和關(guān)系建模將導(dǎo)致的問題。數(shù)據(jù)表由以下這些列組成:

下面是該表內(nèi)的一部分?jǐn)?shù)據(jù):

很明顯就能發(fā)現(xiàn),表中存在很多冗余數(shù)據(jù),如紅框中的部分:

下面將對(duì)三種更新操作:插入,刪除,修改可能出現(xiàn)的異常分別進(jìn)行分析。

1. 插入異常(insertion anomaly)

當(dāng)用戶想要插入某一真實(shí)世界的實(shí)體數(shù)據(jù)時(shí),還必須輸入另一個(gè)真實(shí)世界中實(shí)體的數(shù)據(jù)。

舉例來說,公司業(yè)務(wù)發(fā)展,新建了一個(gè)“家庭主婦團(tuán)”的模式。當(dāng)往表里錄入一個(gè)新的模式時(shí),還必須綁定地錄入一個(gè)新的活動(dòng)。

2. 刪除異常(deletion anomaly)

當(dāng)用戶要?jiǎng)h除某一真實(shí)世界的實(shí)體數(shù)據(jù)時(shí),還必須刪除另一個(gè)真實(shí)世界中實(shí)體的數(shù)據(jù)。

舉例來說,假如刪除下圖紅框中的記錄,就會(huì)導(dǎo)致把“老年人團(tuán)”這種模式的相關(guān)數(shù)據(jù)也給清除掉了。
3. 修改異常(modification anomaly)

當(dāng)用戶要修改某個(gè)值的時(shí)候,同樣的修改操作需要重復(fù)多次。

舉例來說,假如公司為了吸引客戶,決定多送一天,因而需要將”云南七日游“的持續(xù)時(shí)間改為8天。這時(shí)需要改動(dòng)的地方就有三處了,如下圖紅框中所示:

三、函數(shù)依賴

上述的這些更新異常,都可通過規(guī)范化設(shè)計(jì)的方式避免。在詳細(xì)介紹規(guī)范化設(shè)計(jì)之前,首先需要討論一個(gè)重要的概念:函數(shù)依賴(functional dependency)。

函數(shù)依賴:指關(guān)系中每行記錄的某一列(或幾列)的值唯一決定該條記錄另一列的值。總的來說,有以下幾種函數(shù)依賴:

1. 平凡函數(shù)依賴(trivial functional dependency)

指一個(gè)或多個(gè)屬性確定它自己,或者它的子集。如本文樣例數(shù)據(jù)集中TravelCampaignID,TravelCampaignName -> TravelCampaignID就是一個(gè)平凡函數(shù)依賴。需要注意:這種依賴在規(guī)范化中不會(huì)被用到。

2. 增廣函數(shù)依賴(augmented functional dependency)

指某個(gè)依賴式為真,則依賴式左側(cè),或者兩側(cè)同時(shí)增加某語句形成的一種依賴關(guān)系。如本文樣例數(shù)據(jù)集中TravelCampaignID,ModleID -> TravelCampaignName。因?yàn)橹恍枰猅ravelCampaignID就能夠確定TravelCampaignName了。需要注意:這種依賴在規(guī)范化中不會(huì)被用到。

3. 等價(jià)函數(shù)依賴(equivalent functional dependency)

這種依賴關(guān)系是一對(duì)對(duì)的。比如若A->B和B->A都為真,那么A能推出來的,B同樣也能推出來,因此A->B和B->A就被稱作等價(jià)函數(shù)依賴。如本文樣例數(shù)據(jù)集中TravelCampaignID-> TravelCampaignName和TravelCampaignName-> TravelCampaignID。

需要注意:這種依賴只需保留一組依賴關(guān)系即可,但它不屬于規(guī)范化的范疇。

4. 部分函數(shù)依賴(partial functional dependency)

指關(guān)系的一列函數(shù)依賴于組合主碼的一部分。顯然這種依賴中必須存在組合主碼。如本文樣例數(shù)據(jù)中ModelID->ModelName,因?yàn)橛涗浀膹?fù)合主碼(TravelCampaignID, ModelID)能確定記錄的任何一列,ModelID只是該復(fù)合主碼的一部分。需要注意:這種依賴關(guān)系屬于規(guī)范化范疇。

5. 完全函數(shù)依賴(full key functional dependency)

指復(fù)合主碼函數(shù)確定關(guān)系中的其他列,并且復(fù)合主碼的任意部分不能單獨(dú)確定其他列。這個(gè)概念和上面的部分函數(shù)依賴顯然是對(duì)立的。需要注意:這種依賴關(guān)系屬于規(guī)范化范疇。

6. 傳遞函數(shù)依賴(transitive functional dependency)

指非碼列函數(shù)確定關(guān)系中的其他非碼列。如本文樣例數(shù)據(jù)中CampaignManangerID->CampaignManangerName顯然就是一個(gè)傳遞函數(shù)依賴。需要注意:這種依賴關(guān)系屬于規(guī)范化范疇。

以上的六種函數(shù)依賴中,只有后面三種和規(guī)范化設(shè)計(jì)有關(guān)。前面三種因?yàn)閷?duì)改進(jìn)冗余信息并沒有幫助,不納入規(guī)范化過程中。

四、規(guī)范化

規(guī)范化設(shè)計(jì)能夠有效的避免數(shù)據(jù)冗余導(dǎo)致的更新異常,它基于范式思想。一個(gè)關(guān)系是否滿足某種范式,通常要看它是否不包含某個(gè)函數(shù)依賴。

下面首先來看看幾個(gè)范式的定義:

1. 第一范式(1NF)

一個(gè)表如果每一行都是唯一,并且任何行都沒有包含多個(gè)值的列,則它滿足1NF。

對(duì)于關(guān)系表來說,真正的規(guī)范化過程從第二范式開始,因?yàn)殛P(guān)系表本身已經(jīng)滿足1NF了。

2. 第二范式(2NF)

一個(gè)表如果滿足1NF,并且不包含部分函數(shù)依賴,則這個(gè)表滿足2NF。

3. 第三范式(3NF)

一個(gè)表如果滿足2NF,并且不包含傳遞函數(shù)依賴,則這個(gè)表滿足3NF。

至于3NF以上的范式,則基于其他函數(shù)依賴,對(duì)于減少數(shù)據(jù)冗余消除異常,沒有多大幫助。這里就不再介紹了。

對(duì)樣例數(shù)據(jù)進(jìn)行第三范式規(guī)范化后,紅字列對(duì)應(yīng)主碼,結(jié)果如下:

  • 旅行活動(dòng)表:
  • 業(yè)務(wù)經(jīng)理表:
  • 游玩模式表:
  • 旅行活動(dòng) - 游玩模式聯(lián)系表:

現(xiàn)在請(qǐng)自行思考一下,更新異常解決了嗎?答案是肯定的。但是也不能說100%的冗余信息都去除了,比如說外碼的映射關(guān)系就重復(fù)了一次。對(duì)外碼進(jìn)行變更,保證不異常的方法將在第5篇進(jìn)行講解。

五、規(guī)范化的例外情況

并非所有的關(guān)系,都必須滿足3NF,沒有那么絕對(duì)。有些時(shí)候可以考慮降到2NF。

比如下面這個(gè)是某公司銷售經(jīng)理信息表:

這張表并不滿足3NF,因?yàn)猷]編和城市之間存在了部分函數(shù)依賴,從而有信息冗余(見上圖紅框部分)。但由于該公司同一地區(qū)最多只有兩名銷售經(jīng)理,因此冗余情況很少,規(guī)范化到3NF,反而讓表的設(shè)計(jì)顯得過于復(fù)雜了。因此這種情況可以考慮不升級(jí)到3NF,讓上層實(shí)現(xiàn)去解決冗余問題。

六、ER建模,關(guān)系建模與規(guī)范化設(shè)計(jì)

這些建模工作的作用,就是能夠讓設(shè)計(jì)的關(guān)系,更容易滿足規(guī)范化設(shè)計(jì)中的(第三)范式要求,從而減少數(shù)據(jù)冗余,消除更新異常。

在實(shí)際開發(fā)中,絕大部分情況,都是按著ER建模->關(guān)系建模->物理模型建模進(jìn)行開發(fā)的。這樣設(shè)計(jì)出來的表,絕大部分滿足第三范式,只有小部分地方需要調(diào)整,可根據(jù)實(shí)際情況,決定是選用3NF還是2NF,其中前者占大多數(shù)情況。

如果不按這個(gè)套路來,后果就是前文提到的一堆更新異常。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容