資料模型只有在保留重要決策時才有價值。Box 和 arrow 不是目標;真正要留下的是 identity、cardinality、optionality 與 lifecycle。
從規則開始,不要只找名詞
以研究論文平台為例:
- 一篇 paper 屬於一個 venue,一個 venue 有多篇 paper;
- 一篇 paper 至少有一位 author,一位 author 可寫多篇 paper;
- Author order 有意義;
- Paper 可以引用多篇 paper,也可能引用本地 dataset 以外的資料。
名詞提示 entity,動詞與數量才揭露 relationship 和 constraint。
白話來說: 先把名詞畫底線找可能的 table,再把動詞和數量畫底線,找出資料庫真正需要保證的事。
Attribute 之前先處理 identity
Identifier 必須在顯示資料改變後仍然穩定。Author name 不是 identity,因為名字會重複也會更改。單一來源的 author ID 可以作為內部識別;若整合多個 provider,可能需要 surrogate key 加上各來源 identifier。
先列出 candidate keys,再選 primary key。Primary key 是被選中的 candidate,不代表其他 identity rule 不存在。
有系統地轉換 relationship
| Conceptual relationship | Relational mapping |
|---|---|
| One-to-many | Foreign key 放在 many side |
| Optional one-to-many | 若缺席有意義,使用 nullable foreign key |
| Many-to-many | 建立含兩側 foreign key 的 junction table |
| Relationship 有自己的 attribute | Attribute 放在 junction table |
| Recursive relationship | 指回同一 table,或建立 junction table |
Paper authorship 不只是兩個 ID,因為 author order 屬於 relationship:
CREATE TABLE paper_author (
paper_id bigint NOT NULL REFERENCES paper(paper_id),
researcher_id bigint NOT NULL REFERENCES researcher(researcher_id),
author_position integer NOT NULL CHECK (author_position > 0),
PRIMARY KEY (paper_id, researcher_id),
UNIQUE (paper_id, author_position)
);
第一個 constraint 防止同一 author 重複加入;第二個防止兩位 author 佔據同一順位。
Optionality 是商業規則
NOT NULL 或 nullable 不是排版偏好。若 paper 可以在 venue resolution 完成前先匯入,venue_id 可能暫時為 NULL。若對外顯示的 paper 一定要有 venue,應明確建模狀態,而不是永久接受模糊資料。
Cascade 也要跟 lifecycle 一致。刪除 venue 幾乎不該連 paper 一起刪;刪除暫存 import batch 時,連 staging rows 一起清掉則可能合理。
用問題驗證模型
Diagram 整齊不代表模型完成。用代表性的 read 和 write 驗證:
- 能否插入最小的合法 object?
- 哪些不合法狀態會被 schema 拒絕?
- 常用頁面能否直接得到需要的資料?
- 同一 relationship 能否意外出現兩次?
- Referenced entity 被刪除時會發生什麼?
複習卡
- Requirement 提供規則,diagram 負責記錄。
- Identity 應能承受顯示資料變更。
- Cardinality 決定 foreign key 的位置。
- Relationship attribute 放在 junction table。
- Optionality 與 delete action 編碼 lifecycle。
- 用真實操作驗證模型,不用美觀判斷。