Data-model arguments become unproductive when they compare features without naming the workload. The useful question is not “Which database is best?” but “Which facts, queries, and failure modes should be cheap and explicit?”
Model one research dataset four ways
Suppose the system stores papers, researchers, topics, venues, and citations.
Relational
Tables and junction tables make keys, foreign keys, uniqueness, and multi-entity transactions explicit. This is a strong default for reporting and varied joins.
Document
A paper document can embed a bounded author snapshot and topic list so a paper page is one read. Independent researcher profiles and unbounded citations should usually remain referenced.
Graph
Nodes and relationships make citation paths, coauthor neighborhoods, and variable-depth traversals direct. Tabular aggregates and broad scans may be less natural.
Raw-data engine
CSV, JSON, or columnar files can be queried without first loading everything into a database. This shortens time to first query but shifts work into parsing, adaptive indexing, metadata, and repeated access.
In plain terms: every model makes one route feel like a hallway and another feel like climbing through a window. Choose the hallway used by the real workload.
Compare obligations, not slogans
| Question | Relational | Document | Graph | Raw data |
|---|---|---|---|---|
| Strong cross-entity constraints | Strong | More application work | Product-specific | External validation |
| Bounded aggregate read | Join or precompute | Natural embedding | Possible | Reparse or cache |
| Variable-depth relationships | Recursive query | Awkward | Natural | Custom processing |
| Ad hoc tabular analytics | Strong | Requires reshaping | Often secondary | Strong with analytic engines |
| First query before loading | Requires ingestion | Requires ingestion | Requires ingestion | Natural |
| Update ownership | Centralized schema | Aggregate-oriented | Relationship-oriented | File/pipeline-oriented |
Polyglot persistence has a bill
Using several databases can make each local workload elegant, but creates replication lag, failure handling, schema evolution, access control, observability, and on-call burden.
Before adding a second model, specify:
- Which system owns each fact?
- How does derived data catch up?
- What stale result is acceptable?
- How is a failed update replayed safely?
- Can the team operate the system at 3 a.m.?
A decision sequence
- Write the invariants and update boundaries.
- List the highest-volume and highest-latency reads.
- Identify unbounded growth and deep traversals.
- Choose the simplest model that makes the dominant paths natural.
- Prototype the hardest query with realistic data.
- Add another store only when measured limits justify its operational cost.
Review card
- Choose from workload and invariants, not category labels.
- Relational is strong for constraints, transactions, joins, and reporting.
- Document storage fits bounded aggregates read together.
- Graph storage fits relationship traversal.
- Raw-data querying trades loading delay for repeated parsing and indexing work.
- Every additional store creates consistency and operational obligations.
沒有先說 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。