# 資料模型全景：文件/圖/時序/向量

::: tip 核心問題
**為什麼不能把所有資料都塞進 MySQL 的表格裡？** 當你的資料是社交關係網、每秒百萬條的感測器串流、或者 AI 需要理解的語意向量時，關聯式表格就力不從心了。不同的資料形態，需要不同的建模方式。
:::

---

## 1. 關聯式之外：需要其他資料模型的動機

關聯式資料庫（MySQL、PostgreSQL）用「表 + 行 + 列」組織資料，適合結構固定、關聯明確的業務資料。但現實世界的資料遠不止這一種形態：

| 資料形態 | 關聯式的痛點 | 更合適的模型 |
|----------|-------------|-------------|
| 使用者畫像（欄位不固定，巢狀結構） | 頻繁 ALTER TABLE，大量 NULL 列 | **文件模型** |
| 社交網路（朋友的朋友的朋友） | 多層 JOIN 效能指數級下降 | **圖模型** |
| 監控指標（每秒百萬條寫入） | 寫入瓶頸，歷史資料膨脹 | **時序模型** |
| AI 語意搜尋（「意思相近」的內容） | 無法表達語意相似度 | **向量模型** |

::: info 核心觀點
不是「替代」關聯式，而是「補充」。大多數系統的核心業務仍然跑在 MySQL/PostgreSQL 上，但在特定場景引入專用資料模型，能獲得數量級的效能提升。
:::

---

## 2. 文件模型（Document）

### 2.1 文件模型 概述

文件模型將資料儲存為 **JSON/BSON 文件**，每條記錄是一個自包含的文件，可以有不同的欄位結構。

```json
{
  "_id": "user_1001",
  "name": "張三",
  "tags": ["VIP", "活躍"],
  "address": { "city": "北京", "district": "朝陽區" },
  "orders": [
    { "id": "o1", "amount": 299 },
    { "id": "o2", "amount": 599 }
  ]
}
```

**關鍵特點：**
- **無 Schema 約束**：不需要預先定義表結構，欄位隨時增減
- **巢狀結構**：地址、訂單直接嵌在文件裡，一次讀取全部資料
- **水平擴展**：天然適合分片（Sharding），輕鬆應對海量資料

### 2.2 文件 vs 關聯式

| 對比維度 | 關聯式（MySQL） | 文件型（MongoDB） |
|----------|----------------|------------------|
| 資料結構 | 固定 Schema，ALTER TABLE 修改 | 靈活 Schema，隨時加欄位 |
| 巢狀資料 | 需要多表 JOIN | 直接巢狀在文件中 |
| 跨記錄關聯 | JOIN 很強 | 關聯查詢較弱 |
| 適合場景 | 結構穩定的業務資料 | 結構多變的內容資料 |

### 2.3 典型場景

- **CMS 內容管理**：文章、評論、標籤結構各異
- **使用者畫像**：不同使用者有不同的屬性欄位
- **商品目錄**：手機有「螢幕尺寸」，食品有「保存期限」，欄位完全不同
- **設定中心**：各服務的設定結構不統一

::: warning 常見誤區
「MongoDB 不需要設計資料結構」—— 錯！文件模型同樣需要認真設計：巢狀層級不宜過深，頻繁更新的子文件應該拆分為獨立集合。
:::

---

## 3. 圖模型（Graph）

### 3.1 圖模型 概述

圖模型用 **節點（Node）** 和 **邊（Edge）** 表達實體及其關聯。每個節點是一個實體，每條邊是一個關聯，節點和邊都可以攜帶屬性。

```
(張三) --[關注]--> (李四) --[關注]--> (王五)
   |                                    |
   +--------[購買]----> (iPhone) <--[購買]--+
```

### 3.2 圖模型的殺手級能力：多跳查詢

**場景**：在社交網路中找「朋友的朋友的朋友」

關聯式做法（3 層 JOIN）：
```sql
SELECT DISTINCT f3.name
FROM friends f1
JOIN friends f2 ON f1.friend_id = f2.user_id
JOIN friends f3 ON f2.friend_id = f3.user_id
WHERE f1.user_id = 1001;
```

圖資料庫做法（Cypher 查詢語言）：
```cypher
MATCH (me)-[:FOLLOWS*1..3]->(target)
WHERE me.name = '張三'
RETURN DISTINCT target.name
```

關聯式每多一跳，就多一次 JOIN，效能指數級下降。圖資料庫透過指標直接遍歷關聯，多跳查詢效能幾乎不變。

### 3.3 典型場景

- **社交網路**：好友推薦、共同關注、影響力傳播
- **知識圖譜**：實體關聯推理（「誰是誰的老師的學生」）
- **詐欺偵測**：發現資金環路、關聯帳戶網路
- **推薦系統**：基於使用者-商品-標籤的關聯圖推薦

---

## 4. 時序模型（Time-Series）

### 4.1 時序模型 概述

時序模型以 **時間戳記** 為主軸，專門最佳化「按時間順序寫入、按時間範圍查詢」的場景。

```
timestamp            device      cpu_usage   memory
2024-01-15 10:00:01  server-01   45%         12.3GB
2024-01-15 10:00:02  server-01   67%         12.5GB
2024-01-15 10:00:03  server-01   92%         14.1GB
```

### 4.2 不用 MySQL 存時序資料的動機

| 問題 | MySQL | 時序資料庫（InfluxDB） |
|------|-------|----------------------|
| 寫入速度 | 萬級/秒 | **百萬級/秒** |
| 歷史資料 | 手動清理，表越來越大 | **自動過期策略**（TTL） |
| 聚合查詢 | GROUP BY 慢 | **內建降取樣**（5 秒 → 1 分鐘均值） |
| 儲存效率 | 通用儲存，空間浪費 | **列式壓縮**，節省 90% 空間 |

### 4.3 典型場景

- **伺服器監控**：CPU、記憶體、磁碟每秒採集
- **IoT 感測器**：溫度、濕度、GPS 軌跡
- **金融行情**：股票價格、交易量的秒級資料
- **日誌分析**：應用日誌的時間線聚合

---

## 5. 向量模型（Vector）

### 5.1 向量模型 概述

向量模型將文字、圖片、音訊等非結構化資料透過 **Embedding 模型** 轉換為高維數值向量，然後透過計算向量之間的距離來衡量語意相似度。

```
「好吃的日料」 → Embedding → [0.82, 0.15, 0.91, 0.33, ...]
                                    ↓ 餘弦相似度
「銀座壽司之神」  → [0.80, 0.18, 0.89, ...] → 96% 相似
「義大利披薩」    → [0.12, 0.85, 0.20, ...] → 31% 相似
```

### 5.2 向量搜尋 vs 關鍵字搜尋

| 對比 | 關鍵字搜尋（LIKE / 全文索引） | 向量搜尋 |
|------|---------------------------|---------|
| 搜尋方式 | 精確匹配字串 | 語意相似度匹配 |
| 「好吃的日料」 | 只能匹配包含「日料」的文字 | 能找到「壽司」「生魚片」「居酒屋」 |
| 多語言 | 需要分別處理 | 跨語言語意理解 |
| 多模態 | 僅文字 | 文字、圖片、音訊統一檢索 |

### 5.3 典型場景

- **RAG（檢索增強生成）**：為 LLM 提供相關知識片段
- **語意搜尋**：理解使用者意圖而非關鍵字
- **以圖搜圖**：上傳一張圖，找到視覺相似的圖片
- **推薦系統**：基於內容語意的相似推薦

::: tip 向量資料庫的選擇
- **獨立向量資料庫**：Pinecone、Milvus、Weaviate —— 專注向量檢索，效能最優
- **傳統資料庫擴展**：pgvector（PostgreSQL）、Atlas Vector Search（MongoDB）—— 減少架構複雜度
- **記憶體向量庫**：FAISS、Annoy —— 適合小規模、低延遲場景
:::

---

## 6. 選型決策：選擇資料模型的方法

| 你的資料長什麼樣？ | 推薦模型 | 代表產品 |
|-------------------|---------|---------|
| 結構固定，關聯明確（訂單、使用者） | 關聯式 | MySQL、PostgreSQL |
| 結構靈活，巢狀層級多（內容、設定） | 文件型 | MongoDB、DynamoDB |
| 實體之間關聯複雜，需要多跳遍歷 | 圖 | Neo4j、Amazon Neptune |
| 按時間順序寫入，按時間範圍查詢 | 時序 | InfluxDB、TimescaleDB |
| 非結構化資料，需要語意相似度搜尋 | 向量 | Pinecone、Milvus、pgvector |

::: info 實戰建議
現代系統通常是**多模型混用**：
- **核心業務**用 PostgreSQL（關聯式）
- **使用者行為日誌**用 InfluxDB（時序）
- **AI 知識庫**用 Milvus + pgvector（向量）
- **推薦引擎**用 Neo4j（圖）

不要追求「一個資料庫解決所有問題」，而是讓每種資料找到最合適的家。
:::

<DataModelsDemo />
