關聯資料表正規化(Normalization)--前言

我覺得程式設計師,除了要有好的程式設計技術外,還要有一點層度的資料庫底子,最基本也是最重要的是SQL語言,但在SQL語言之前還有一個更重要的事,就是進行關聯資料表的正規化,正規化前置作業做的好,後面寫程式時才不會綁手綁腳。常常看到資料庫討論區裡的問題,可能有一半都是正規化有問題,導致後面程式開發出問題。

在台灣工作分類不是很清楚,常常是Code、Program、DB、SA…全部都是在同一個人身上,台灣的各位同志,每個都是超人,每每參加研討會,常可聽到講師問這些工作誰做?怎麼又是你,你們公司有沒有什麼職稱的人?怎麼又是你!台下笑的很開心,台上可是眉頭深鎖。

我想要透過一個工作上的實例來說明正規化,公司常與大陸(China)做生意,所以內部系統裡需要規劃出一個全大陸地區資訊表格,大陸相當的大,他們在地區規格設計上和台灣並不相同,複雜所多,我們來看看。

China Area Design

  • 大陸地區都市及城市分類複雜,最大的為「區域」:即一般稱東北、西北、華中、華南、華北、華東等六大區域。
  • 大陸都市又分為一級都市及二級都市。
  • 依「行政區」來劃分又分四種:省級、自治區、直轄市、特別行政區。
依上述資料,我們可以建議出以下Schema:ChinaArea(省級、一級、二級、區域、行政區)

跑出來的資料會像這樣:

省級  一級      二級      區域  行政區
内蒙古 呼和浩特市   清水河县    华北  自治区
内蒙古 呼伦贝尔市   新巴尔虎右旗  华北  自治区
山西  吕梁市     中阳县     华北  省级
河北  衡水市     武邑县     华北  省级
内蒙古 锡林郭勒盟   锡林浩特市   华北  自治区
河北  衡水市     深州市     华北  省级
河北  石家莊市    行唐县     华北  省级
山西  临汾市     大宁县     华北  省级
河北  邢台市     南和县     华北  省级
内蒙古 乌兰察布市   察哈尔右翼后旗 华北  自治区

看起來很完美,但其實裡面問題重重,我們接下去看。

更新異常(Update Anomaly)

更新異常是指在更新「值」時所發生的異常。例如上面結果省級中,有多筆「内蒙古」「河北」「山西」等多筆重覆資料,在區域中「华北」更新不斷重覆,行政區中「自治区」「省级」亦同。這樣重覆值在我們需要更新資料時,需同時更新多筆資料,不然會造成資料不一致

例如,如果有一天「河北」重新規劃,不在是華北,而改為華中,那以上述資料來說,就必須同時更新四筆資料,不然就會造成更新異常的情況。

刪除異常(Deletion Anomaly)

刪除異常是指在刪除「值」時所發生的異常。
舉例,我們想把二級「中阳县」的資料刪除,
「山西 吕梁市 中阳县 华北 省级」
但你會發現,你會一併一級「吕梁市」資料刪除,這樣就會造成刪除異常。原因是你把一級、二級資料綁在一起,所以造成遷一髮動全身。

新增異常(Insertion Anomaly)

新增異常是指在新增「值」時所發生的異常。大陸的建設很快,可能常常有重劃、遷村等可能性,假設因為重劃,我新增一筆資料,但因為還不確定二級名稱,所以無二級資料:

省級  一級    二級    區域  行政區
内蒙古 呼和浩特市 Null    华北 自治区

如果你的Schema設計時二級沒有設定為可Null,那就會產生錯誤。

為什麼要正規化

就上述而言正規化要解決二個問題:
  1. 資料重覆
    Eliminating Redundancy,建立沒有重覆資料的關聯表,重覆資料不只浪費空間,還會造成資料維護上的問題。
  2. 更新、刪除、新增異常
    Eliminating Inconsistent Dependency,資料相依是指關聯表中屬性之間(省級、一級、二級…)擁有關係,如果擁有不一致的資料相依,那就會在更新、刪除、新增當成異常。
正規化的優點:
  • 資料查詢快
    正規化的查詢速度比不上未正規化,因為正規化後的關聯表必須透過「join」來還原,但跟所產生的異常相比,正確的資料才是最重要的。

    沒有留言:

    張貼留言

    感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。