1.3 数据模型与选型:JSON 文档的先天优势


文档摘要

1.3 数据模型与选型:JSON 文档的先天优势 本节摘要:Elasticsearch 的数据单位是文档(document)——一个自包含的 JSON 对象,字段类型由映射(mapping)约定。本节对比文档模型与关系模型的建模差异,解释反范式(冗余换查询)为何在搜索场景成立,并给出"该不该引入 Elasticsearch"的选型判断。看完这节,doc-1001 的户籍档案就齐了。 先看结论:什么时候不该用 Elasticsearch 把结论前置:需要事务、需要频繁局部更新、需要严格外键约束、数据量撑死几十万还要模糊搜索——这些场景数据库加个全文索引扩展也许更合适。Elasticsearch 的甜区是:全文检索、多维过滤加统计、日志与时间序列、规模超出单机数据库承受力。

1.3 数据模型与选型:JSON 文档的先天优势

本节摘要:Elasticsearch 的数据单位是文档(document)——一个自包含的 JSON 对象,字段类型由映射(mapping)约定。本节对比文档模型与关系模型的建模差异,解释反范式(冗余换查询)为何在搜索场景成立,并给出"该不该引入 Elasticsearch"的选型判断。看完这节,doc-1001 的户籍档案就齐了。

先看结论:什么时候不该用 Elasticsearch

把结论前置:需要事务、需要频繁局部更新、需要严格外键约束、数据量撑死几十万还要模糊搜索——这些场景数据库加个全文索引扩展也许更合适。Elasticsearch 的甜区是:全文检索、多维过滤加统计、日志与时间序列、规模超出单机数据库承受力。它为读优化、为搜索而生,代价在写端与一致性端:没有跨文档事务,更新是"取旧、改好、重写",近实时的可见性默认有一秒延迟。

选型不是信仰问题,先看真实约束再动手。

同一条工单,两种建模

doc-1001 在关系世界里长这样:工单主表一行,扩展属性表若干行,标签表再挂三行——查询时三表连接。在文档世界里,它是一条自包含的 JSON:

{ "ticket_id": "doc-1001", "title": "用户申请退款,处理速度太慢", "status": "pending", "priority": 2, "assignee": { "name": "陈舟", "team": "售后一组" }, "tags": ["退款", "时效", "投诉"], "created_at": "2026-08-20T10:17:00Z", "metrics": { "first_reply_minutes": 42, "resolve_hours": 0 } }

对应的表结构则是另一种风格:

CREATE TABLE ticket ( id VARCHAR(32) PRIMARY KEY, title VARCHAR(200) NOT NULL, status VARCHAR(16), priority TINYINT, assignee_name VARCHAR(32), assignee_team VARCHAR(32), created_at TIMESTAMP ); CREATE TABLE ticket_tag ( ticket_id VARCHAR(32), tag VARCHAR(32) );

差别在哲学:关系模型消灭冗余,一条标签只在标签表出现一次;文档模型拥抱冗余,把一次查询需要的所有信息打进同一份文档。搜索恰恰是"一次取整条、按内容挑"的访问模式——文档模型与它天作之合。反范式带来的更新麻烦(改负责人要重写整条工单)在搜索场景代价可控:工单的更新频率远低于查询频率。

两种建模思路的取舍矩阵

两种建模思路的取舍矩阵

字段与映射:文档的户籍

文档里的每个字段在首次写入时被推断类型,也可以在建索引时用映射显式声明:title 是 text(会被分词建倒排)、status 是 keyword(整体精确匹配)、priority 是整数、created_at 是日期。同一字段还能同时以两种形态存在——text 存检索形态,keyword 子字段存聚合与过滤形态。映射是文档的户籍登记表,第 3 章会整章展开,这里先记住一条纪律:类型一旦定下,改动只能重建索引,因为倒排结构随类型一起生成。

选型判断:三问三答

遇到"要不要上 Elasticsearch",我的习惯是问三个问题:

  1. 查询模式是不是"按内容找"?模糊匹配、多词组合、相关性排序占大头,就是。
  2. 数据规模与增速是否超出数据库舒适区?百万级以下、无分词需求,数据库的全文扩展往往够用。
  3. 能否接受最终一致?搜索结果晚一秒可见通常无害,但库存扣减这种强一致操作绝不能搬过来。
场景 推荐方案 理由
商品站内搜索、工单检索 Elasticsearch 分词、打分、聚合一条龙
订单账务、库存扣减 关系型数据库 事务与约束是硬需求
结构化日志与指标 Elasticsearch 加采集管道 时间序列写多读多,分片天然横向扩展
千行小表的关键词查找 数据库即可 引入集群的运维成本大于收益

💡 关键直觉:数据库是"事实的唯一来源",搜索引擎是"查询的加速视图"。成熟架构常常两者并存——写库为真,异步同步进搜索引擎服务查询,这是第 9 章案例的主线之一。

考核与自测

考核知识点清单

考核点 达标标准
文档自包含 说出文档模型与关系表模型在冗余上的相反取舍
反范式代价 解释改负责人为何要重写整条工单,以及搜索场景为何可接受
双形态字段 说出 text 与 keyword 各自买到什么能力,何时共用一个字段
选型三问 用查询模式、规模、一致性三问判定一个真实场景
架构定位 说出"数据库为源、搜索引擎为视图"的分工与异步同步的衔接
弱项清单 说出无跨文档事务、更新即重写、近实时可见三个代价各自的业务后果

易错点补充

  • 把搜索引擎当主数据库:事务、外键约束、强一致都不在它的能力清单里,先定事实源再定查询视图,顺序不能反。
  • 为"将来可能要搜"把所有字段都建成 text:倒排有构建与存储成本,只给真正参与检索的字段建索引,纯展示字段设 index 为 false。
  • 默认同步是实时的:数据库到搜索引擎通常是异步批量同步,产品文案里的"实时"要对齐这个预期,否则就是给自己埋投诉。
  • 文档里塞进只有报表用的巨型字段:_source 原样保存所有内容,取回成本随体积线性上涨,超长内容考虑单独索引或外链存储。
  • 迁移时逐字段照搬表结构:把关系表的列一对一搬成字段,等于带着连接的思维用文档引擎,先按查询重组再迁移。

带着地图上路

  • 文档是自包含 JSON,反范式是搜索场景的合理选择,冗余换来的是读取时的一跳到位。
  • 映射约定字段类型,text 与 keyword 是同一文本的两种形态,各司其职。
  • 选型看查询模式、规模与一致性容忍度,三者有其一不匹配就慎重。
  • 常见落地形态:数据库为源、搜索引擎为视图,异步同步衔接两端。

概念齐了,下一章动手:二十分钟搭好单节点,把 doc-1001 真正送进引擎。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U