資料庫規範化三個正規化應用例項(轉)

gugu99發表於2007-08-13
資料庫規範化三個正規化應用例項(轉)[@more@]

  規範化為什麼重要?目前很多的資料庫由於種種原因還沒有被規範化。本文中解釋了其中一些原因,並用不同形式的正規化(normal form)規範化了一個保險公司的理賠表。在這個過程中表的改變以及新增的一些附加表使資料庫效率更高、錯誤更少、更容易維護。

  資料庫的規範化是最佳化表的結構和把資料組織到表中的實踐,這樣做資料才能更明確。規範化使你能夠改變業務規則、需求和資料而不需要重新構造整個系統。

  透過改變儲存資料的方式--僅僅改變一丁點--並改變訪問這些資訊的程式,你就可以消除很多錯誤或垃圾資料出現的機會並減輕更新資訊所必要的工作量。

  公司現實存在的一個問題可以用一句話概括"我們一般都這樣做"。我們一般像採用那種方式儲存資訊;我們一般允許人們把任何資訊寫入;我們一般採用那種方式程式設計。這通常是一件壞事,特別是對於年輕的和正在學習的公司來說。但是,當有新的系統和更好的完成任務的途徑的時候,有時"採用那種方式任務完成得很好"這句話可能需要重新探討和修改。規範化資料就是公司常常採用的有益的方式之一。

  儘管對於COBOL程式(例如任何COBOL程式設計師都熟悉的檔案佈局)使用資料來說,把它們(資料)儲存在關聯式資料庫中與儲存在平面檔案中很相似,但是儲存在平面檔案中的方法並不是完成任務的必要的最好的途徑,特別是由於你不瞭解兩者之間的差別或害怕改變,而簡單地把過去的觀念帶入到現在的方式。

  注意:Dictionary.com是這樣定義規範化的:"使其標準,特別使導致它符合某種標準或規範。"或"某種標準的強制接受"。Webopedia認為規範化是"在關聯式資料庫設計中,組織資料以最小化冗餘的過程。規範化通常包括把一個資料庫分成兩個或多個表並定義表之間的關係。其目標是隔離資料,這樣新增、刪除和修改某個欄位只需要在一個表中進行,接著可以透過定義的關係傳遞到資料庫中剩餘的表中"。我更喜歡這個定義。

  術語

  在你瞭解現實世界中的一個保險公司的例子之前,你需要了解一些在討論中會用到的術語。處理資料庫的時候,特別是在處理規範化問題的時候,下面一部分講到的一組新的關鍵字很有作用:

  · 關係(Relation):從本質上說,關係是一個包含行和列的二維表或陣列。

  · 關聯(Relationship):關聯是不同表之間的資料彼此聯絡的方法。關聯同時存在於形成不同實體的資料項之間和表實體本身之間,構成了資料庫規範化的基本核心問題。資料關聯有三種基本的型別,對它們有所瞭解是很重要的:

  一對一(1:1):一對一關聯意味著任何給定的每個(而不是大多數)例項嚴密地與另一個實體的一個例項對應。每個人只有一個正確的指紋就是唯一的。每個電話號碼準確地與一個付帳的獨立私人客戶對應(不是公司)。美國的每個人都只有一個社會保障號碼。

  一對多(1:M):一對多關聯意味著給定實體的一個例項可以可以與另一個實體的零個例項、一個例項或者多個例項關聯。每個人可能沒有小孩、有一個小孩或多個小孩。每個人可能沒有汽車、有一輛汽車或多輛汽車。

  多對多(M:N):多對多關聯(給定實體的零個、一個或多個例項與另一個實體的零個、一個或多個例項關聯)是一種直接模擬很複雜的關聯,它經常被分解為多個1:M關聯。由於多個家庭混合在一起,一個或多個小孩可能沒有父母親(孤兒)、一個父母(單親家庭),多於一個父母(兩個仍然在一起或者離婚的兩個父母、或者離婚了又復婚了的父母)。房屋或財產可以轉讓給一個人或多個人,而這些人(一個或多個)在遺囑上可能又一個或多個房屋或財產。

  · 屬性(Attribute):屬性被認為是程式或資料庫中的某些元件的可以修改的特性或特徵,它可以被設定為不同值或者關係或表中的列。

  · Tuple:Tuple是關聯式資料庫或非關聯式資料庫中的排序了的一組值或值屬性:關係中的一行。

  · 刪除異常:刪除異常指由於其它資料故意的刪除而導致的資料矛盾或未預料到的資料(資訊)丟失。

  · 插入異常:插入異常指由於資料的缺少或缺乏導致沒有能力把資訊新增到資料庫。

  · 更新異常:更新異常指由於資料冗餘或者冗餘資料的不完整更新造成的資料矛盾。

  · 關係的分解:關係的分解指把一個關係分解成多個關係,從而使關係符合更高的正規化。

  · 資料冗餘:資料冗餘指資料庫中沒有必要的資料重複。

  · 資料完整性:資料完整性指資料庫中資料的一致性。保證資料完整性很重要,只有這樣使用者才知道他們依賴的資料是正確的、他們查詢的結果以及程式才是精確的和符合期望的。

  · 原子值:原子值是一個值,它既不是能被進一步拆分的一組值,也不是一個重複的組。每個列都有一個完整的值,但是隻有一個值--這個值不能被分解為多個部分,它要麼被資料庫使用,要麼被使用資料庫的使用者訪問的資訊。

  · 參考完整性規則:參考完整性規則指儲存在非空的外部健中的值必須是某種關係中的關鍵資料項。

  · 外部健:外部健是一個關係中的一組屬性(一個或多個列),它同時也是某種(相同的或其它的)關係中的主鍵。它是關係之間的邏輯連結。參考自己關係的外部健稱為遞迴外部健。

  · 功能依賴:功能依賴意味著一行中某個屬性的值由該行中另一個屬性的值決定。這通常出現在主鍵(使某行唯一的資訊片斷)與該行的其它資訊之間。城市和州的組合依賴於Zip(郵政)程式碼,即使給定的一個州中有很多Zip程式碼與某個城市關聯。美國的每個合法的人員身份依賴於他的社會保障號碼。

  · 決定性:功能依賴左邊的屬性決定行中其它屬性的值(Zip程式碼決定了城市和州;社會保障號碼決定了人的身份;執照號碼和州決定了汽車的擁有者)。

  · 實體完整性規則:實體完整性規則指某一行的關鍵屬性可能為空(如果你在某個城市就有一個Zip程式碼;如果你有一輛汽車就有一個執照號碼)。

  · 約束:約束是一種規則,它限定了資料庫中的值。電話號碼必須是數字的;美元數量必須是數字的;state必須是合法的州或省;country必須是合法的國家;日期不能是2月31號。

  現在你已經知道了很多相關的術語了,我們可以看看相關術語中規範會的意義了。下面的例子並不是典型的僱員?經理?部門示例,也不是學生?教授?課程提供示例。我將演示一個假設的保險公司的資料庫。資料庫中的表比本示例中用到的要複雜得多,但是與人們遇到的比較相近。

  圖1顯示了理賠(claim)表的非規範化定義。儘管在某個保險公司的資料庫中的表比它多得多,但是這些表為我們提供了一些背景,透過它我們可以看到規範化和其分支。請記住每個章節中的示例都只有部分列,這樣就簡化了示例並使你輕易地看到發生變化的東西。

  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

  圖1:未規範化的理賠表的列

  第一正規化(1NF)

  把資料庫或資料庫的錶轉換為第一正規化一般都相當簡單。第一正規化要求消除資料中重複的組,這是透過建立相關資料的單獨表來實現的。它透過觀察資料和表結構來確定表以完成第一正規化。

  第一正規化是透過把重複的組放到每個獨立的表中,把這些表透過一對多關聯聯絡起來這種方式來消除重複組的。

  沒有重複的屬性以及沒有重複的一組值--這聽起來足夠簡單了。但是,有時候由於沒有其它的選擇,使人們相信只有簡單地給設計新增任何其它集合卻很困難,但是這也是你所做的事情。

  如果我們想使理賠表達到第一正規化,我們就需要找到真正與某個理賠相關聯的所有屬性。到底是什麼構成了理賠?

  · 理賠要有編號。

  · 理賠要有提出要求的人。

  · 理賠要有報告日期。

  · 理賠要有事故或生病日期。

  · 理賠要有由於事故或者生病引起的某種物品保留的數量。

  · 理賠屬於或者依據某種策略編寫。

  · 理賠能夠結束。

  · 理賠能夠重新開始。

  · 理賠有某種覆蓋面嗎?或者某種策略有更多的的事情?

  · 理賠有起因嗎?或者事故或生病有起因嗎?

  · 支付了理賠嗎?或者支付了發票嗎?

  · 理賠有社會保障號碼嗎?或者有時候某個社會保障號碼屬於提出要求的人嗎?

  · 死亡日期是個有趣的部分。理賠的人死亡了嗎?沒有,但是如果是生命保險,它可能與理賠相關,因此應該留著。

  修改與理賠直接相關的列,得到的結果如圖2所示:

  CLAIM_NUM、 CLAIM_STATUS、 ACCIDENT_YR、 ACCIDENT_DT、 REPORTED_DT、 ENTERED_DT、 CLOSED_DT、 DEATH_DT、 ASSIGNED_DT、 ADJSTER_CD、 ADJUSTER_NAME、 AGENT_CD、 AGENT_NAME、 AWARD_CD、 AWARD_DESC、 PAYMENT_NUM、 LOCATION、 SITE、 DEDUCTIBLE_RECOVER、DEDUCTIBLE_REMAIN、 POLICY_NO、 POLICY_DESCRIPTION、 STATE、 RUN_DT、 ACTIVITY_DT、 ENTRY_DT、 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、 GROSS_PD

  圖2:第一正規化的理賠表

  符合第一正規化的理賠表修訂版本將包含僅僅與理賠相關的資訊,沒有包含支付或發票、策略或事故。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-954239/,如需轉載,請註明出處,否則將追究法律責任。

資料庫規範化三個正規化應用例項(轉)
請登入後發表評論 登入
全部評論

相關文章