# 数据模型全景：文档/图/时序/向量

::: 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 />
