COPYRIGHT CH CHAN 2008


Creative Commons License


This work is licensed under a
Creative Commons Attribution-Share Alike 3.0 Unported License.
以中文寫多次。如要轉載請標示本文作者及以同樣的 CC Attribution-Share Alike 再發表。

-------------------------------

上次講到 Excel 的問題。我們的數據如此。比上一例子加入了病人覆診的醫院及醫院位置。我們試行將數據正規化。

nor1.png

正規化分開三部曲。第一部曲叫做 1NF (First normal form) ,要求數據合乎三點。

a. 每筆數據(橫行)要有獨特的 id (Unique Key)
b. 每一直行只能輸入一個獨立(atomic)值
c. 沒有重覆的組(Group)

可能你會覺得好難明。只要抱著 Learn by doing 的心態,要明不難。
一個 Excel 試算表,在 database 的術語,叫做 table 。而一個關聯式數據庫( rational database ),是由多個 table 所組成。我們試下透過修改我們的 table 去達至 1NF 。

a. 每筆數據(橫行)要有獨特的 id (Unique Key)

每一個數據,即示 Excel 的每一個橫行,都應該有一個獨立的 id 。病人的 id 我們可以用身份證號碼,總之每個人的 id 都要有不同。因此病人名稱不能是獨立 id ,因為世上可以有幾萬人叫做 Wong 。假定因為私隱問題我們不能獲得病人的身份證號碼,我們只好自行創造一個 PatID (Patient ID) 。這是常見的做法。總之大原則係,我講 PatID 係 1 ,你知我講係果個 Wong ,而唔係黃毓民或者黃世澤。修改後的樣子是這樣的。

nor2.png

b. 每一直行只能輸入一個獨立(atomic)值

獨立(atomic)值,是指每一個空格,只能輸入一件物件。例如 Disease 欄,每一格理應只輸入一個病症。想當然的做法,是這樣的。就是加入 Disease1, Disease2, Disease3....

nor3.png

但要是有個病人有四個病怎算?再者,例如我們要找出發燒的病人,我們要找遍 Disease1 至 DiseaseN 有沒有出現 Fever 。多麼的費時失事。故此我們有 c 原則。

c. 沒有重覆的組(Group)

這個原則,指我們的 Table 設計,不能有多過一個直行是收集同一樣的數據。上例的 Disease1 、 Disease2 和 Disease3 就是有違此原則。因為三個直行都是收集邏輯上同樣的數據。
那麼我們應如何將每人可能多於一件的數據加入一個直行 ((Database 術語叫做 One to Many relationship)) ,而又不違以上原則?
我們需要直向思考,如圖。

nor41.png

方法如此,但我不會用文字寫出來。
可是這樣做又是有問題的。這個 Table 是表示病人的資料,可是每一個橫行不是代表一個病人。一般的數據庫軟件都不容許 PatID 這樣子重覆。(但從圖片所見, Excel 是可以的)解決的方法,是將所有病拉出來。設立一個新的 Table ,叫做 Diseases ((通常 Table 名會用眾數, Column 名用單數)) 。方法是這樣的。

nor51.png

由於在 Diseases table 每一個 disease 都會佔一個橫行,所以我們根據 a 原則要加入一個獨特 id (DisID) ,現時每個 table 的獨特 id 都會用紅色表示,在 database 術語,紅色的叫做 Primary Key 。在 Diseases Table 也見到綠色的 PatID ,這個叫做 foreign key ,我們可透過參考 Patients Table 得知那個 PatID 代表誰人。 ((日後有機會會講到 Inner Join ))
至這一步,我們解決了每一格只許輸入一個數據的問題。下一篇要解決的問題,是 data integrity 的問題。(即是 FeVR 和 Fever 的問題)亦即是,這個數據庫未完整正規化。