NoSQL 的分类逻辑
NoSQL 不是一个产品类别,而是按数据模型与访问模式分出的若干族:文档、键值、宽列、搜索、列式分析、时序、图。它们的取舍点各不相同,选型的正确顺序是先写清查询模式、数据规模与一致性要求,再倒推该用哪一族,而不是先挑热门产品再想办法塞需求。
基本信息
| 分类主线 | 数据模型 + 访问模式 |
|---|---|
| 一致性口径 | 强一致 / 最终一致 / 可调一致性 |
| 事务能力 | 单文档事务、多行事务、跨分片事务差异很大 |
| 落地建议 | 关系库能扛住就先别加组件,确有瓶颈再引入 |
| 兜底做法 | 组合方案:交易主存储 + 检索副本 + 分析副本 |
选型的判断顺序
- 先列核心查询:点查、范围扫描、全文检索、聚合分析、关系遍历,各自什么形态
- 再定数据量与写入速率:每天写多少、保留多久、冷热是否分层
- 然后定一致性:能否接受最终一致,是否需要跨行事务与读己之写
- 接着算运维成本:集群、副本、备份、升级需要多少人力和机器
- 最后才是对照类别选产品,并用真实规模的数据做一次压测
类别对照
| 类别 | 数据模型 | 代表产品 | 典型场景 |
|---|---|---|---|
| 文档库 | JSON/BSON 文档 | MongoDB | 内容、订单、用户档案等半结构化数据 |
| 键值库 | key → value | Redis、Memcached | 缓存、会话、计数器 |
| 宽列库 | 行键 + 列族 | HBase、Cassandra | 超大规模写入、稀疏列 |
| 搜索引擎 | 倒排索引 + 文档 | Elasticsearch | 全文检索、日志分析 |
| 列式分析库 | 列式存储 + SQL | ClickHouse、Doris | OLAP 聚合、报表 |
| 时序库 | 时间戳 + 标签 | InfluxDB、Prometheus | 监控指标、IoT 采集 |
| 图数据库 | 顶点 + 边 | Neo4j 等 | 关系网络、路径查询 |
同一需求的多库示例
同一需求的多库示例
查询某个用户最近 10 条订单:
- MongoDB: db.orders.find({ userId: 7 }).sort({ ts: -1 }).limit(10)
- Elasticsearch: GET /orders/_search {"size": 10, "query": {"term": {"userId": 7}}, "sort": [{"ts": "desc"}]}
- ClickHouse: SELECT * FROM orders WHERE userId = 7 ORDER BY ts DESC LIMIT 10
- Redis: ZREVRANGE orders:7 0 9
同一条需求四种写法都能实现,差别在于:能否按任意条件过滤、
是否支持更新、写入延迟、聚合能力与运维成本——这些才是选型依据。常见误配
| 误配 | 问题 | 更合适的选择 |
|---|---|---|
| 拿搜索库当唯一主存储 | 事务与更新一致性弱,写入成本高 | 关系库/文档库做主存,搜索库做检索副本 |
| 用时序库跑业务订单查询 | 标签模型不支持任意条件过滤与大范围更新 | 列式分析库或关系库 |
| 用键值库存复杂对象 | 只能按键取,按值查询做不了 | 文档库 |
| 用宽列库做实时聚合报表 | 聚合能力弱,需要应用层拼 | 列式分析库 |
| 用文档库扛全文检索 | 分词与相关度调优能力有限 | 搜索引擎 |
大多数业务系统是组合方案:关系库做交易主存储,搜索库做检索,列式库做分析,键值库做缓存;先画清数据流与一致性边界,再定组件清单。
「支持 SQL」不等于同类能力:不同库的 SQL 方言、事务范围与一致性语义差别很大,别把能跑 SELECT 当成可以直接迁移。
引入一个分布式存储意味着长期承担集群、副本、备份与升级的运维成本;如果一个关系库加索引就能满足,多引入的组件通常只会增加故障面。