這裡的內容來自我的老師 David White 的課以及他的書 Data Modelling The Foundation of Information Systems。目前沒有附 ERD 圖,所以可能有些地方不是很容易懂。
命名
當命名物件跟屬性時需符合以下規則:
- 使用單數詞作名字,不用複數詞。這樣子能更容易自動產生正確的描述句(程式可以自動判斷把單數詞改為複數詞)。
- 只使用一種命名規則(CamelCase 或者 Underscore_Naming),不要混用。
- 名字要能描述功能,比如說一個紀錄元件安裝時間的欄位該命名為 WhenComponentInstalled 而不只是 WhenInstalled ,不然在範圍外會跟其他要安裝的欄位造成混淆。試著讓文法正確。
- 當使用某些通用的詞(如 description),應該在詞前面添加形容詞(如 ProductDescription)
當命名屬性時需符合以下規則:
- 人名欄位的命名使用 GivenName(名)與 FamilyName(姓),這兩個命名沒有文化隔閡,也沒有宗教或禮俗上的含意。使用一般常見的 FirstName 或 LastName 則會導致不同文化上的理解錯誤。
(註:也可考慮提供使用者另外一個欄位,專門存放使用者自己想要看到的姓名)
- 多添加形容詞以避免混淆。但是在那些 Foreign Key 的欄位,還是該前置該 Key 原來的名字,以便識別。
- 不要使用像是 "Count" 這樣的 SQL 保留字來命名,因為資料庫不能接受這些名字。
- 非必要不要用 "Date" 來命名。資料庫系統有 date/time 類型的欄位,而原本設計是 Date 的欄位常會後來要改成 date/time 。使用 WhenXxxYyy 來命名 date/time 欄位,比如說 WhenEnrolled、WhenContractStarts、WhenContractEnds。
常見的命名問題
- 使用複數詞作名字
- 沒有依照大眾普遍接受的方式縮寫
- 英文大小寫方式不一致
- 英文動詞時態不一致,如 WhenXxxBegan 相對於 WhenXxxEnds。
- 名字不夠清楚,如 WhenInstalled 沒有標示安裝什麼東西。
- 使用太過廣義的詞,如 Description 。
- 名字欄位使用 LastName、ChristianName 等有文化差異性的命名法。
- Foreign Key 的命名沒有前置原表的名字。比如說 Customer 應該改為 AnybodyCustomer ,才能一看就知道這欄位由 Anybody 這個 table 而來。
表格 table 設計
表格應該代表一個物件不會改變的本質,而不是會改變的狀態。舉例來說,一個學校管理資料庫常常會有學生 Student 與職員 Employee 兩個表格,但是這樣子的設計沒有考量到職員也能來修課當學生的狀況,學生與職員都是一種可變動的身份,所以不應該拿來當作表格名稱。在這個情況使用「人 Person」當作表格的設計會更有彈性,因為「人」是本質,不會隨著時間改變。而會改變的狀態,通常使用一個欄位來表示。
繼承與類別
「人」這個概念也有狹義的時候,比如說交易時對象不一定會是人,有時候也是會有公司機關之類的,所以在民法上有「自然人」以及「法人」這兩種概念。在這個時候,使用「Anybody 主體」這個母類別表格,然後下面繼承「Person自然人」「Organization法人」兩種子類別表格,能夠做出更加有彈性的架構。當使用繼承這種機制的時候,要注意幾個事項:
- 子類別必須是永久性的,就如自然人永遠不會變成法人。
- 子類別必須是母類別之內的,如 Person 跟 Organization 都是 Anybody。
- 各個子類別的欄位不能完全相同,不然就失去分開類別的意義了。
- 各個子類別必須有本質上的不同,如自然人是活著的,而法人是概念上的,雖然兩者都能成為簽署合約。
相同的繼承概念也能夠使用在「交通工具→汽車、飛機」上。
時間概念
萬事都會隨著時間而改變,而資料庫最好是設計成會紀錄這些改變,以便將來能查訊。通常一個事件有開頭也有結尾,以 WhenBegan 還有 WhenEnded 來命名。WhenEnded不會是主鍵,因為主鍵不能為 null。
對自身的關聯 Recursive Association
一個表格可以對本身作關聯,比如說管理人這種關係。如果每個人只能有一個管理人,那麼可以直接對表格本身的 PK 作關聯,這被稱為樹狀自身關聯(Tree Recursion)。如果一個人能有複數的管理人,那就必須新增一個 Supervision (管理)表格,有兩個 FK :PersonBeingSupervised 以及 PersonSupervisor ,這被稱為網路自身關聯(Network Recursion)。
狀態
如先前所探討的,事物除了能用不變的本質來區分外,也能用他們的行為或是發生在他們的事情等等依著時間發生的「狀態」來區分。就如同犯罪的人可被歸類為罪犯,簽了員工合約的人成為員工,繳了學費的成為學生。這些被視為狀態的改變,而要對這些狀態作區分就必須紀錄狀態改變的事件。
舉學生報名作為例子,也許我們必須紀錄以下的事件:遞交日、審核日、核可日、取消日等等。如果這些都放在 StudentEnroll 的表格上,那麼以後要增加新的狀態就必須更改整個 ERD 。為了改善這種問題,我們可以把事件集中放在另一個表格中,並且新增一個事件類別的表格。這樣子能讓狀態轉移事件有更大的彈性。