沒有先說 workload 的 data-model 爭論,最後通常只剩功能表比較。真正有用的問題不是「哪個 database 最好」,而是「哪些 fact、query 與 failure mode 應該便宜而且明確」。
同一份研究資料用四種方式建模
假設系統保存 paper、researcher、topic、venue 與 citation。
Relational
Table 與 junction table 能明確表達 key、foreign key、uniqueness 與 multi-entity transaction。對 report 與多樣 join 是很強的預設。
Document
Paper document 可以 embed 有上限的 author snapshot 與 topic list,讓 paper page 一次讀完。獨立 researcher profile 與無上限 citation 通常仍應 reference。
Graph
Node 與 relationship 讓 citation path、coauthor neighborhood 與 variable-depth traversal 變直接。Tabular aggregate 和 broad scan 則可能不自然。
Raw-data engine
CSV、JSON 或 columnar file 可以在尚未完整 load 進 database 前直接 query,縮短 first query 時間,但 parsing、adaptive indexing、metadata 與 repeated access 的成本仍要支付。
白話來說: 每種模型都會讓某條路像走廊,另一條路像翻窗。應該選真實 workload 最常走的那條走廊。
比較 obligation,不比較口號
| 問題 | Relational | Document | Graph | Raw data |
|---|---|---|---|---|
| 強 cross-entity constraint | 強 | 更多 application work | 依產品而定 | 外部驗證 |
| Bounded aggregate read | Join 或 precompute | Natural embedding | 可以做到 | Reparse 或 cache |
| Variable-depth relationship | Recursive query | 不自然 | 強項 | Custom processing |
| Ad hoc tabular analytics | 強 | 需要 reshape | 通常是次要用途 | 搭配 analytic engine 很強 |
| Load 前先 query | 需要 ingestion | 需要 ingestion | 需要 ingestion | 自然 |
| Update ownership | Centralized schema | Aggregate-oriented | Relationship-oriented | File/pipeline-oriented |
Polyglot persistence 有帳單
多種 database 能讓各自的 local workload 很漂亮,也會帶來 replication lag、failure handling、schema evolution、access control、observability 與 on-call 負擔。
增加第二種 model 前,先回答:
- 每個 fact 由哪個 system 擁有?
- Derived data 如何追上 source?
- 可以接受多 stale 的結果?
- Failed update 如何安全 replay?
- 團隊能否在凌晨三點操作它?
決策順序
- 寫出 invariant 與 update boundary。
- 列出最高 volume 與最高 latency 的 read。
- 找出 unbounded growth 與 deep traversal。
- 選擇讓 dominant path 最自然的最簡單模型。
- 用 realistic data prototype 最困難的 query。
- 只有 measured limit 足以支付維運成本時,才增加另一種 store。
複習卡
- 從 workload 與 invariant 選擇,不從 category label 選擇。
- Relational 適合 constraint、transaction、join 與 reporting。
- Document 適合一起讀取的 bounded aggregate。
- Graph 適合 relationship traversal。
- Raw-data query 用 loading delay 交換 repeated parsing/indexing work。
- 每增加一種 store,就增加 consistency 與 operation obligation。