关系型数据库的边界

关系型数据库统治数据存储几十年,ACID 事务、SQL 生态、强一致是它的护城河。但业务场景一旦偏离它的设计假设,短板就暴露出来:高并发读写的热点行会被锁拖住;海量数据的水平扩展要靠分库分表手工打理;灵活的文档结构要反复建表迁移;图关系查询要用一串 JOIN 慢慢爬。

NoSQL 不是"不用 SQL",而是"针对特定数据模型与访问模式设计的存储引擎"。它牺牲一部分通用性,换取吞吐、弹性或灵活模型上的极致表现。选型的前提是先承认没有银弹:同一套系统里,关系库、KV、文档库、搜索引擎各司其职才是常态。

本文核心知识点
  • 文档型MongoDB 为代表的灵活结构。
  • KVRedis 为代表的高性能缓存。
  • 列族HBase、Cassandra 的海量写入。
  • 图Neo4j 的关系遍历。
NoSQL 选型配图:蓝紫渐变背景中央发光圆盘以三条柔和曲线分别连接左侧纯色圆柱体、右上圆球体与右下方形盒,扁平科技插画
一个枢纽通向三种形态各异的容器,正是按数据形态选择存储的意象。

NoSQL 四大类

NoSQL 按数据模型大致分四类。键值存储 Redis、Memcached:数据是 key-value,读写极快,适合缓存、会话、计数器;文档型 MongoDB:数据是 JSON 文档,字段结构灵活,适合内容、用户资料、日志类数据;列族存储 HBase、Cassandra:按列族组织,写入吞吐极高,适合海量时序与事件数据;图数据库 Neo4j:以节点和边建模,适合社交关系、推荐、风控图谱。

选型先看访问模式,再看数据模型:按主键读单条选 KV,按文档整体读写选文档型,按行键范围扫描海量数据选列族,按关系遍历选图。数据模型与访问模式匹配,比对比基准测试数字重要得多。

文档型与 KV

MongoDB 的文档模型对"结构会变"的数据特别友好:用户资料字段可以按需增减,数组与嵌套天然表达一对多,分片集群让写容量水平扩展。它的短板是事务能力弱于关系库,多文档事务有性能成本,跨分片事务更贵,关联查询靠聚合管道而非 JOIN。

Redis 是 KV 之王,但它的角色要摆正:内存是贵的,Redis 适合热数据与高频小数据,不是全量存储。做缓存要设计过期与淘汰,做计数器要小心原子性,做排行榜用有序集合,做分布式锁要关注过期续期。Redis 的能力来自丰富的数据结构,而不是"能存多少"。

# Redis 典型场景的命令形态
SET session:1001 "json" EX 1800   # 会话缓存
ZADD rank:score 9527 "user1"      # 排行榜
INCR counter:uv:20261028          # 计数器
SETNX lock:order:888 uuid EX 10   # 分布式锁

列族与图数据库

HBase 与 Cassandra 适合海量写入与范围扫描。HBase 基于 LSM 树与行键有序存储,写吞吐高,按行键前缀扫描极快,适合用户行为流水、消息记录;Cassandra 的分布式写模型天然多活,可用性优先,适合跨机房部署的 IoT 与事件系统。列族的代价是查询模式受限,没有行键的查询就是全表扫描,设计行键等于设计查询。

图数据库把关系当一等公民。好友推荐、风控团伙识别、最短路径这类"关系即查询"的场景,用图数据库比关系库 JOIN 快几个量级。Neo4j 用 Cypher 声明式遍历,社交二度人脉、知识图谱推理都是它的主场。图库的选型提醒:图查询写起来爽,但要管理好索引与遍历深度,防止全图扫描。

一致性模型

NoSQL 的分布式设计普遍遵循 BASE 理念:基本可用、软状态、最终一致。选型时必须把一致性需求摊开讲清楚:钱包余额能不能最终一致?不能,必须强一致;点赞数、浏览数能不能最终一致?能,允许短暂不一致换取吞吐。

Redis 主从复制有秒级延迟,读从库可能读到旧值,缓存场景可接受;MongoDB 副本集默认读主写主,可以配置读偏好到从库但会弱一致;Cassandra 用可调一致性,写 QUORUM 读 QUORUM 才能保证多数派一致。一致性不是"选强还是弱",而是按数据分级:核心数据留关系库,边缘数据上 NoSQL,各自用合适的语义。

一致性分级
  • 强一致资金、库存、订单状态,留在关系库。
  • 最终一致点赞、浏览、动态流,可上 NoSQL。
  • 可调一致Cassandra 按读写配 QUORUM。

选型决策矩阵

把候选引擎放进一张决策矩阵,按五个维度打分:数据模型匹配度、读写性能、扩展性、一致性满足度、运维成本。模型不匹配直接一票否决;一致性不满足需求直接排除;剩下在性能与运维之间权衡,小团队优先运维友好的,大流量再上需要专职运维的引擎。

# 一个简化的决策示例
场景:用户动态流 + 关系型核心订单
动态流   -> MongoDB(文档 + 水平扩展)
热缓存   -> Redis(KV + 过期)
核心订单 -> MySQL(强一致 + 事务)
关系推荐 -> Neo4j(图遍历)

混合架构不可避免,关键是画清楚数据流:谁写入、谁同步、谁兜底。多引擎之间的数据同步用消息队列与定时对账,谁也不能假设对方永远在线。