首页/数据/NoSQL 速查/模式演进:无模式不等于免治理
选型与架构50 条

模式演进:无模式不等于免治理

文档库与搜索库放宽了建表约束,但数据形态依然随业务演进:新增字段、改类型、拆合字段都要有迁移计划。通行做法是版本字段加双写回填再切读,搜索库受映射限制还要走重建索引加别名切换。

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

无模式不等于免治理

文档库与搜索库放宽了建表约束,但数据形态仍然随业务演进:新增字段、改类型、拆合字段随时发生。没有迁移计划就会长期停留在「新旧两种形态并存、代码里到处是兼容分支」的状态。通行做法是给文档打版本号,按「双写新形态 → 后台回填存量 → 切读新形态 → 清理旧字段」推进;搜索库受映射限制,类型变更必须走重建索引加别名切换。

迁移推进步骤

  • 新增字段先以可选形态上线,写入端同时写新旧两处(双写)
  • 后台限速回填存量数据,按主键分批并记录进度与失败项
  • 读取端切换为主读新字段,保留短期新旧兼容分支
  • 观察稳定后清理旧字段与兼容代码,避免形态长期并存
  • 搜索库与列式库单独排期:前者重建索引换别名,后者按版本支持的方式重写列

文档库:版本字段与渐进迁移

文档库:版本字段与渐进迁移
// 文档带 schemaVersion,读取端兼容新旧两种形态
{ _id: 1, schemaVersion: 2, name: "ann", profile: { city: "hz" } }

// 回填:按版本条件分批处理,每批完成后记录进度
// 步骤:双写新字段 → 后台回填存量 → 切读新字段 → 稳定后清理旧字段
db.users.updateMany(
  { schemaVersion: 1 },
  { $set: { profile: { city: "$legacyCity" }, schemaVersion: 2 } }
)

// 回填期间用索引支撑范围挑选,避免每批都全表扫描
// db.users.createIndex({ schemaVersion: 1, _id: 1 })

搜索库:映射变更走重建

搜索库:映射变更走重建
# 字段类型无法原地修改:建新索引 → reindex → 别名切换
curl -X PUT "localhost:9200/users_v2" -H 'Content-Type: application/json' \
  -d '{"mappings":{"properties":{"profile":{"properties":{"city":{"type":"keyword"}}}}}}'

curl -X POST "localhost:9200/_reindex" -H 'Content-Type: application/json' \
  -d '{"source":{"index":"users_v1"},"dest":{"index":"users_v2"}}'

curl -X POST "localhost:9200/_aliases" -H 'Content-Type: application/json' \
  -d '{"actions":[{"remove":{"index":"users_v1","alias":"users"}},{"add":{"index":"users_v2","alias":"users"}}]}'

变更类型与处理方式

变更文档库搜索库 / 列式库
新增可选字段直接写入,读取端按缺省值处理新增映射后新文档可用,历史文档按缺省值返回
新增必填字段先双写并回填,再在写入端加强校验映射加字段后需要 reindex 才能补齐历史数据
字段类型变更按版本字段双写后切换通常必须重建索引并切换别名
字段改名双写两处,切读后再删旧名可加字段别名过渡,仍可能需要重建
删除字段读取端先不依赖,再清理写入删除映射字段同样需要重建索引
ClickHouse 侧新增列可以带上 DEFAULT 先上线,再按需执行 MATERIALIZE COLUMN 重写历史分区;修改列类型要核对当前版本支持的转换范围,不确定时走「新建列 + 回填 + 切换」路线。
回填必须限速并分段:全量回填与线上写入争抢资源,中途失败还要能按进度重跑,因此每批要有幂等条件与进度记录。

易错点

  • 直接修改搜索库映射的字段类型:请求会被拒绝,缺少重建与别名流程就会卡在变更窗口里
  • 一次性全量回填大集合且不限速:回填流量与线上写入互相抢占,期间查询延迟明显上升
  • 旧形态长期不清:兼容分支越积越多,后续每次改字段都要同时照顾两套结构
  • 回填任务不做进度记录与幂等:中断后只能从头再来,或者重复处理同一批数据造成写放大

数据来源与参考

  • MongoDB Manual: Schema versioning
  • Elasticsearch Guide: Mapping
  • ClickHouse Docs: ALTER TABLE
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌