數(shù)據(jù)庫規(guī)范化三個(gè)范式應(yīng)用實(shí)例

字號:

規(guī)范化為什么重要?目前很多的數(shù)據(jù)庫由于種種原因還沒有被規(guī)范化。本文中解釋了其中一些原因,并用不同形式的范式(normal form)規(guī)范化了一個(gè)保險(xiǎn)公司的理賠表。在這個(gè)過程中表的改變以及添加的一些附加表使數(shù)據(jù)庫效率更高、錯誤更少、更容易維護(hù)。
    數(shù)據(jù)庫的規(guī)范化是優(yōu)化表的結(jié)構(gòu)和把數(shù)據(jù)組織到表中的實(shí)踐,這樣做數(shù)據(jù)才能更明確。規(guī)范化使你能夠改變業(yè)務(wù)規(guī)則、需求和數(shù)據(jù)而不需要重新構(gòu)造整個(gè)系統(tǒng)。
    通過改變存儲數(shù)據(jù)的方式--僅僅改變一丁點(diǎn)--并改變訪問這些信息的程序,你就可以消除很多錯誤或垃圾數(shù)據(jù)出現(xiàn)的機(jī)會并減輕更新信息所必要的工作量。
    公司現(xiàn)實(shí)存在的一個(gè)問題可以用一句話概括"我們一般都這樣做"。我們一般像采用那種方式存儲信息;我們一般允許人們把任何信息寫入;我們一般采用那種方式編程。這通常是一件壞事,特別是對于年輕的和正在學(xué)習(xí)的公司來說。但是,當(dāng)有新的系統(tǒng)和更好的完成任務(wù)的途徑的時(shí)候,有時(shí)"采用那種方式任務(wù)完成得很好"這句話可能需要重新探討和修改。規(guī)范化數(shù)據(jù)就是公司常常采用的有益的方式之一。
    盡管對于COBOL程序(例如任何COBOL程序員都熟悉的文件布局)使用數(shù)據(jù)來說,把它們(數(shù)據(jù))存儲在關(guān)系數(shù)據(jù)庫中與存儲在平面文件中很相似,但是存儲在平面文件中的方法并不是完成任務(wù)的必要的好的途徑,特別是由于你不了解兩者之間的差別或害怕改變,而簡單地把過去的觀念帶入到現(xiàn)在的方式。
    注意:Dictionary.com是這樣定義規(guī)范化的:"使其標(biāo)準(zhǔn),特別使導(dǎo)致它符合某種標(biāo)準(zhǔn)或規(guī)范。"或"某種標(biāo)準(zhǔn)的強(qiáng)制接受"。Webopedia認(rèn)為規(guī)范化是"在關(guān)系數(shù)據(jù)庫設(shè)計(jì)中,組織數(shù)據(jù)以小化冗余的過程。規(guī)范化通常包括把一個(gè)數(shù)據(jù)庫分成兩個(gè)或多個(gè)表并定義表之間的關(guān)系。其目標(biāo)是隔離數(shù)據(jù),這樣添加、刪除和修改某個(gè)字段只需要在一個(gè)表中進(jìn)行,接著可以通過定義的關(guān)系傳遞到數(shù)據(jù)庫中剩余的表中"。我更喜歡這個(gè)定義。
    術(shù)語
    在你了解現(xiàn)實(shí)世界中的一個(gè)保險(xiǎn)公司的例子之前,你需要了解一些在討論中會用到的術(shù)語。處理數(shù)據(jù)庫的時(shí)候,特別是在處理規(guī)范化問題的時(shí)候,下面一部分講到的一組新的關(guān)鍵字很有作用:
    · 關(guān)系(Relation):從本質(zhì)上說,關(guān)系是一個(gè)包含行和列的二維表或數(shù)組。
    · 關(guān)聯(lián)(Relationship):關(guān)聯(lián)是不同表之間的數(shù)據(jù)彼此聯(lián)系的方法。關(guān)聯(lián)同時(shí)存在于形成不同實(shí)體的數(shù)據(jù)項(xiàng)之間和表實(shí)體本身之間,構(gòu)成了數(shù)據(jù)庫規(guī)范化的基本核心問題。數(shù)據(jù)關(guān)聯(lián)有三種基本的類型,對它們有所了解是很重要的:
    一對一(1:1):一對一關(guān)聯(lián)意味著任何給定的每個(gè)(而不是大多數(shù))實(shí)例嚴(yán)密地與另一個(gè)實(shí)體的一個(gè)實(shí)例對應(yīng)。每個(gè)人只有一個(gè)正確的指紋就是的。每個(gè)電話號碼準(zhǔn)確地與一個(gè)付帳的獨(dú)立私人客戶對應(yīng)(不是公司)。美國的每個(gè)人都只有一個(gè)社會保障號碼。
    一對多(1:M):一對多關(guān)聯(lián)意味著給定實(shí)體的一個(gè)實(shí)例可以可以與另一個(gè)實(shí)體的零個(gè)實(shí)例、一個(gè)實(shí)例或者多個(gè)實(shí)例關(guān)聯(lián)。每個(gè)人可能沒有小孩、有一個(gè)小孩或多個(gè)小孩。每個(gè)人可能沒有汽車、有一輛汽車或多輛汽車。
    多對多(M:N):多對多關(guān)聯(lián)(給定實(shí)體的零個(gè)、一個(gè)或多個(gè)實(shí)例與另一個(gè)實(shí)體的零個(gè)、一個(gè)或多個(gè)實(shí)例關(guān)聯(lián))是一種直接模擬很復(fù)雜的關(guān)聯(lián),它經(jīng)常被分解為多個(gè)1:M關(guān)聯(lián)。由于多個(gè)家庭混合在一起,一個(gè)或多個(gè)小孩可能沒有父母親(孤兒)、一個(gè)父母(單親家庭),多于一個(gè)父母(兩個(gè)仍然在一起或者離婚的兩個(gè)父母、或者離婚了又復(fù)婚了的父母)。房屋或財(cái)產(chǎn)可以轉(zhuǎn)讓給一個(gè)人或多個(gè)人,而這些人(一個(gè)或多個(gè))在遺囑上可能又一個(gè)或多個(gè)房屋或財(cái)產(chǎn)。
    · 屬性(Attribute):屬性被認(rèn)為是程序或數(shù)據(jù)庫中的某些組件的可以修改的特性或特征,它可以被設(shè)置為不同值或者關(guān)系或表中的列。
    · Tuple:Tuple是關(guān)系數(shù)據(jù)庫或非關(guān)系數(shù)據(jù)庫中的排序了的一組值或值屬性:關(guān)系中的一行。
    · 刪除異常:刪除異常指由于其它數(shù)據(jù)故意的刪除而導(dǎo)致的數(shù)據(jù)矛盾或未預(yù)料到的數(shù)據(jù)(信息)丟失。
    · 插入異常:插入異常指由于數(shù)據(jù)的缺少或缺乏導(dǎo)致沒有能力把信息添加到數(shù)據(jù)庫。
    · 更新異常:更新異常指由于數(shù)據(jù)冗余或者冗余數(shù)據(jù)的不完整更新造成的數(shù)據(jù)矛盾。
    · 關(guān)系的分解:關(guān)系的分解指把一個(gè)關(guān)系分解成多個(gè)關(guān)系,從而使關(guān)系符合更高的范式。
    · 數(shù)據(jù)冗余:數(shù)據(jù)冗余指數(shù)據(jù)庫中沒有必要的數(shù)據(jù)重復(fù)。
    · 數(shù)據(jù)完整性:數(shù)據(jù)完整性指數(shù)據(jù)庫中數(shù)據(jù)的一致性。保證數(shù)據(jù)完整性很重要,只有這樣用戶才知道他們依賴的數(shù)據(jù)是正確的、他們查詢的結(jié)果以及程序才是精確的和符合期望的。
    · 原子值:原子值是一個(gè)值,它既不是能被進(jìn)一步拆分的一組值,也不是一個(gè)重復(fù)的組。每個(gè)列都有一個(gè)完整的值,但是只有一個(gè)值--這個(gè)值不能被分解為多個(gè)部分,它要么被數(shù)據(jù)庫使用,要么被使用數(shù)據(jù)庫的用戶訪問的信息。
    · 參考完整性規(guī)則:參考完整性規(guī)則指存儲在非空的外部健中的值必須是某種關(guān)系中的關(guān)鍵數(shù)據(jù)項(xiàng)。
    · 外部?。和獠拷∈且粋€(gè)關(guān)系中的一組屬性(一個(gè)或多個(gè)列),它同時(shí)也是某種(相同的或其它的)關(guān)系中的主鍵。它是關(guān)系之間的邏輯鏈接。參考自己關(guān)系的外部健稱為遞歸外部健。
    · 功能依賴:功能依賴意味著一行中某個(gè)屬性的值由該行中另一個(gè)屬性的值決定。這通常出現(xiàn)在主鍵(使某行的信息片斷)與該行的其它信息之間。城市和州的組合依賴于Zip(郵政)代碼,即使給定的一個(gè)州中有很多Zip代碼與某個(gè)城市關(guān)聯(lián)。美國的每個(gè)合法的人員身份依賴于他的社會保障號碼。
    · 決定性:功能依賴左邊的屬性決定行中其它屬性的值(Zip代碼決定了城市和州;社會保障號碼決定了人的身份;執(zhí)照號碼和州決定了汽車的擁有者)。
    · 實(shí)體完整性規(guī)則:實(shí)體完整性規(guī)則指某一行的關(guān)鍵屬性可能為空(如果你在某個(gè)城市就有一個(gè)Zip代碼;如果你有一輛汽車就有一個(gè)執(zhí)照號碼)。
    · 約束:約束是一種規(guī)則,它限定了數(shù)據(jù)庫中的值。電話號碼必須是數(shù)字的;美元數(shù)量必須是數(shù)字的;state必須是合法的州或省;country必須是合法的國家;日期不能是2月31號。
    現(xiàn)在你已經(jīng)知道了很多相關(guān)的術(shù)語了,我們可以看看相關(guān)術(shù)語中規(guī)范會的意義了。下面的例子并不是典型的雇員―經(jīng)理―部門示例,也不是學(xué)生―教授―課程提供示例。我將演示一個(gè)假設(shè)的保險(xiǎn)公司的數(shù)據(jù)庫。數(shù)據(jù)庫中的表比本示例中用到的要復(fù)雜得多,但是與人們遇到的比較相近。
    圖1顯示了理賠(claim)表的非規(guī)范化定義。盡管在某個(gè)保險(xiǎn)公司的數(shù)據(jù)庫中的表比它多得多,但是這些表為我們提供了一些背景,通過它我們可以看到規(guī)范化和其分支。請記住每個(gè)章節(jié)中的示例都只有部分列,這樣就簡化了示例并使你輕易地看到發(fā)生變化的東西。
    CLAIM_NUM、 OCCURANCE_NUM 、 CLAIM_STATUS、 ACCDNT_YR、 ACCDNT_DT、 REPORTED_DT、 ENTERED_DT、 CLAIM_DT1、 CLAIM_DT2、 CLAIM_DT3 、 CLAIM_DT4、 CLAIM_DT4 、 CLAIM_DT5 、 CLAIM_DT6 、 CLAIM_DT7、 CLAIM_DT8 、 CLAIM_DT9 、 CLAIM_DT10、 CLOSED_DT 、 DEATH_DT、 ASSIGNED_DT、 ADJSTER_CD 、ADJUSTER_NAME 、 AGENT_CD 、 AWARD_CD 、 CAUSE_CD 、 CAUSE_DESC、 LOCATION 、 SITE 、 COVERAGE_CD 、 COVERAGE_DESC、 DED_RECOV、 DEDUCTIBLE_REMAIN 、 PAID_1 、 RESERVED_1 、 PAID_2 、 RESERVED_2 、 PAID_3 、 RESERVED_3 、 PAID_4 、 RESERVED_4 、 PAID_5 、 RESERVED_5 、 PAID_6 、 RESERVED_6 、 PAID_7 、 RESERVED_7 、 PAID_8 、 RESERVED_8、 PAID_9 、 RESERVED_9 、 PAID_10 、 RESERVED_10 、 LEGAL_FLG、 KEY1、 KEY2、 KEY3、 KEY4、 KEY5、 KEY6、 KEY7、 KEY8、 KEY9、 KEY10、 SEVERITY_CD 、 POLICY_NUM 、 PAYMENT_NUM 、 SSN、 STATE、 ACTVY_DT、 ENTRY_DT、 ADMIN_CD、ADMIN_DESC、 REOPEN_DT、 INSURED_NAME、 INSURED_ADDRESS、 INSURED_PHONE、 INSURED_CITY、 INSURED_STATE、 INSURED_ZIP、 CLAIMANT_NAME、 CLAIMANT_ADDRESS、 CLAIMANT_CITY、 CLAIMANT_STATE、 CLAIMANT_ZIP、 CLAIMANT_PHONE、 SPECIAL_DT_1 、 SPECIAL_DT_2、 SPECIAL_DT_3、 SPECIAL_DT_4 、 SPECIAL_DT_5、 SPECIAL_DT_6 、 SPECIAL_DT_7 、SPECIAL_DT_8 、SPECIAL_DT_9 、 SPECIAL_DT_10 、 GROSS_PD、 POLICY_ID