首页/数据/NoSQL 速查/NoSQL 常见使用反模式
选型与架构50 条

NoSQL 常见使用反模式

多数线上问题来自几类反模式:无界增长的数组与文档、未锚定的正则全扫、把搜索库当主存储、深分页、单调分片键热点、过量索引拖慢写入。识别手段是看查询清单与增长趋势,而不是等出故障再补。

NoSQL 速查数据更新于 2026-10-13

NoSQL 常见反模式是什么

多数线上问题来自几类反复出现的反模式:文档内无界增长的数组、未锚定的正则全扫、把搜索库当主存储、深分页、单调分片键造成写热点,以及集合上堆积过量索引拖慢写入。识别手段是定期清理查询清单与观察数据增长趋势,而不是等出故障再补。这些反模式共同的根源是违背了引擎的设计假设,理解存储与索引机制后再对照自己的用法,问题往往一眼可见。

基本信息

无界数组文档膨胀、写放大,最终撞上文档大小上限
未锚定正则全集合扫描,CPU 占用高
搜索库当主库刷新、合并与恢复语义不适合交易数据
深分页skip 十万时每页越翻越慢
单调分片键写热点集中在单个分片
过量索引写入放大、内存占用高

反模式与修正

反模式后果修正方向
文档内无界数组文档膨胀、写放大、达到大小上限拆子集合或按时间窗分桶
未锚定正则全集合扫描,CPU 高前缀锚定或改用全文检索
把搜索库当主库刷新与恢复语义不适合交易数据主存储用数据库,搜索库做检索副本
深分页 skip 十万每页越翻越慢键集或游标分页
单调键做分片键写热点集中在单个分片散列分片键或复合键
集合上建十几个索引写入放大、内存占用高按查询清单裁剪与合并索引

典型使用场景

  • 建模评审:新增数组字段前先问它会增长到多大
  • 查询审计:把线上真实查询按模式归类,找全表扫描来源
  • 索引治理:定期清理未被使用的索引
  • 分页改造:把深分页接口换成游标翻页
  • 增长监控:对文档平均大小与集合数据量做趋势告警

无界数组的改造示意

无界数组的改造示意
// 反模式:events 数组无限追加
// { _id: 1, events: [ ... 长期增长 ... ] }

// 修正:拆成子集合,按 (ownerId, ts) 建索引
db.user_events.insertOne({ ownerId: 1, ts: new Date(), type: "login" })
db.user_events.createIndex({ ownerId: 1, ts: -1 })   // 便于按时间倒序查最近事件
反模式的共同点是违背引擎的设计假设:先理解存储与索引机制,再对照自己的查询与增长模式排查,比逐条试错快得多。
用短生命周期的正则查询掩盖建模问题最危险:数据量上涨后扫描成本成倍增加,而查询写法看起来完全正常。
索引不是越多越好,每个索引都要在写入时维护,按真实查询清单保留必要的那几个即可。

易错点

  • 用短生命周期的正则查询掩盖建模问题,数据量上涨后扫描成本成倍增加
  • 为每个可能字段建索引:写入延迟与内存上升,收益却来自少数高频查询
  • 数组字段无界增长:等文档接近大小上限才发现,改造需要数据迁移
  • 把搜索库当主存储使用,事务与一致性需求无法满足

数据来源与参考

  • MongoDB Manual: Data modeling
  • Elasticsearch Guide: General recommendations
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌