07 · NoSQL 选型:文档 / 列族 / 图
"要不要上 NoSQL"是个伪命题——先问你的数据是什么形状。本篇按数据形状给四种存储分分工:关系型、文档型、列族型、图型,并给出选型判断框架。
速览卡
| 项 | 内容 |
|---|---|
| 一句话定位 | 按"数据形状 + 访问模式"选存储,而不是追热点 |
| 核心内容 | 文档/列族/图各自的强项、与关系型的分工、选型决策树 |
| 读完能回答 | 我的数据该放关系型还是文档型?列族数据库到底解决什么问题? |
| 相关板块 | DB01 关系模型 | DB04 Schema 设计 | C10 数据建模与数据访问 |
一、先按"数据形状"分
| 类型 | 代表 | 数据形状 | 强项 |
|---|---|---|---|
| 关系型 | MySQL / Postgres | 规整、关系复杂、强约束 | 事务、JOIN、一致性 |
| 文档型 | MongoDB | 自包含、schema 多变 | 灵活、水平扩展容易 |
| 键值型 | Redis / DynamoDB | 简单键值、超高吞吐 | 缓存/计数/会话 |
| 列族型 | HBase / Cassandra | 海量、稀疏、按列扫 | 大数据写入与聚合 |
| 图型 | Neo4j | 关系即一等公民 | 多跳关系查询 |
判断第一问:我的数据是"规整表"还是"自包含文档"?是多跳关系还是海量时序?
二、文档型:什么时候它比关系型顺手
| 场景 | 文档型更顺 | 关系型更好 |
|---|---|---|
| Schema 频繁变 | ✅ 不用 ALTER 迁移 | ❌ 每次改表 |
| 数据自包含(订单=订单+条目) | ✅ 一次读全 | ⚠️ 要 JOIN/子文档 |
| 强一致性 + 复杂事务 | ❌ 弱 | ✅ |
| 跨实体关联查询 | ❌ 弱 | ✅ |
典型判断:先规整后变化 → 关系型;先灵活后固化 → 文档型。 别为了"灵活"放弃事务:业务强一致场景(订单、账务)仍然首选关系型。
三、列族型:不是"列多",是"按列族存储"
列族数据库(HBase/Cassandra)解决的是海量写入 + 按列族聚合:
text
行存储:一行所有列在一起,适合"按行取整条"
列族存储:同一列族的数据聚在一起,适合"海量行、只取少数列"| 场景 | 合适 |
|---|---|
| 海量日志/事件,写远大于读 | ✅ |
| 时间序列、IoT 传感器数据 | ✅ |
| 复杂事务、多变查询 | ❌ |
别被名字误导:列族 ≠ "很多列的关系表"。它是为写入吞吐与列级扫描设计的。
四、图型:关系本身才是数据
当查询的**核心是"多跳关系"**时,图数据库才值得:
| 查询 | 关系型(多表 JOIN) | 图型 |
|---|---|---|
| 朋友的朋友 | 递归/多层 JOIN,慢 | 一条 MATCH (a)-[:FRIEND*2]->(b) |
| 最短路径/社交圈 | 极难写 | 原生支持 |
| 简单关联列表 | ✅ 合适 | 大材小用 |
判断框架:如果 90% 的查询都是 1~2 跳、且数据规整,关系型 + 索引就能覆盖;图型是"跳数深 + 关系动态"时的专用选择。
五、选型决策树
text
数据要不要强事务/JOIN/约束?
├─ 要 → 关系型(MySQL / Postgres)
└─ 不要 →
数据形状?
├─ 自包含、多变 → 文档型(MongoDB)
├─ 海量稀疏、按列扫 → 列族型(HBase / Cassandra)
├─ 简单键值、超高吞吐 → 键值型(Redis / DynamoDB)
└─ 多跳关系 → 图型(Neo4j)一条重要提醒:多数业务系统是关系型为主 + Redis 缓存 + 一个专用存储(搜索/时序/向量)。 "全 NoSQL"或"全不上 NoSQL"都不对,按数据形状组合。
六、自检清单
- [ ] 能按数据形状说出文档/列族/图各自的适用场景
- [ ] 知道"灵活 schema"不等于"放弃一致性"
- [ ] 知道列族存储是为写入吞吐与列扫描设计
- [ ] 知道图型是"多跳关系"专用,不滥用
- [ ] 选型会先问"强事务/JOIN/约束要不要"
- [ ] 能接受"关系型为主 + 专用存储"的组合
七、常见误区
| 误区 | 事实 |
|---|---|
| "NoSQL 比 SQL 快" | 快在特定访问模式,不是通用结论 |
| "MongoDB 能替代 MySQL" | 事务与 JOIN 是关系型的强项 |
| "列族=很多列" | 列族存储是按列族聚堆,为列扫描设计 |
| "图数据库最强大" | 只在多跳关系场景有优势,其余大材小用 |
| "选了 NoSQL 就不用建模" | 反而更考验建模(反范式/分区键) |
| "一种存储走天下" | 按数据形状组合才是常态 |
八、动手练习
练习 A:给数据分类
给以下数据选存储并说明理由:用户账号、订单+明细、好友关系、设备上报的百万级时序、文章与标签。
练习 B:判断是否该迁 MongoDB
场景:一个 CMS,文章结构经常加字段、文章自包含(正文+作者+标签)。要不要迁文档型?迁移会失去什么?
练习 C:设计图模型
用 Neo4j 的 Cypher 语法写出"查找 3 跳内认识的人"的查询,并对比它在关系型里的难度。
相关文档
本区
- 01 · 关系模型与 SQL 基础 —— 关系型的前提
- 05 · Redis 与缓存模式 —— 键值型的典型用途
- 09 · 搜索引擎 ES —— 搜索是另一个专用存储
- 11 · pgvector 向量检索 —— 向量是另一个专用形态
其他域
- 10 · 数据建模与数据访问 —— ORM 与多存储访问