设计文档中“views”字段与“options”字段分别控制哪些行为?
解读
在国内 CouchDB 岗位面试中,这道题考察的是对设计文档(design document)核心结构的掌握程度。面试官通常不会满足于“views 放视图、options 放选项”这种表面回答,而是希望候选人能精确说出两个字段的生效范围、可配置项以及对查询性能、索引更新策略、复制行为的影响。答得越贴近生产调优经验,越能体现“用过、踩过、调过”。
知识点
-
views
位于design_doc.views,本质是 Map/Reduce 定义集合。- 一级 key 是视图名称,二级必须包含 map 函数字符串,可选 reduce 函数字符串。
- CouchDB 会为每个视图建立 B+ 树索引(.view 文件),索引粒度到分片副本级。
- 视图索引的更新时机由 stale、update_seq 等查询参数控制,但索引重建策略、并发度、日志刷盘等细节由 options 字段决定,而非 views 本身。
- 国内常见误区:把 validate_doc_update 写在 views 里;正确做法是放在 design_doc.validate_doc_update,与 views 同级。
-
options
位于design_doc.options,是一个扁平对象,仅对该 design doc 下的所有视图生效,可理解为“局部配置覆盖”。- local_seq(bool):是否把更新序列号写进索引文件,默认 false;开启后可用
startkey_docid+update_seq做增量拉取,但会 显著增加索引体积,国内移动同步场景慎用。 - include_design(bool):是否把 design doc 自身作为结果返回,默认 false;调试时打开,生产关闭。
- partitioned(bool,3.x 分区数据库专用):声明该 design 是否用于分区查询,一旦设为 true,视图结果集自动带上分区键过滤,跨分区查询直接报错,是 国内做租户隔离 时的利器。
- seq_indexing(bool):是否启用序列号索引,与 local_seq 类似但实现不同,3.2 之后已合并。
- raw_collation(bool):是否关闭 Unicode 排序规则,国内对中文排序有特殊要求 时可开启,但会导致与 Erlang 默认排序不一致,需全链路验证。
- after_update(string):自定义 Erlang 模块,用于在索引提交后触发钩子,国内金融场景 用来做 T+1 对账通知。
注意:options 不会随视图查询参数动态变化,修改后必须重建索引才能生效,因此线上变更需走灰度。
- local_seq(bool):是否把更新序列号写进索引文件,默认 false;开启后可用
答案
views 字段用于定义 Map/Reduce 视图,决定“查什么、怎么聚合”;options 字段用于微调该 design 下所有视图的索引构建与返回行为,如是否记录序列号、是否分区、排序规则等。一句话:views 管数据逻辑,options 管索引策略。
拓展思考
- 国内某 SaaS 厂商把 options.partitioned=true 与 db._partition 结合,实现“租户级视图隔离”,但发现租户删除后视图残留。解决思路:在 design doc 里加 after_update 钩子,监听分区删除事件并异步清理 .view 文件,避免全库压缩。
- 如果面试官追问“如何在不重建索引的前提下热更新 options”,可以答:CouchDB 3.3 开始支持 design doc 增量复制+视图分片级缓存失效,但 local_seq、raw_collation 等关键选项仍强制重建;生产环境建议 双 design 灰度,通过 alias 视图 切换流量。