1.3 Elasticsearch-索引、文档、字段、映射—与 MySQL 的类比

Elasticsearch与MySQL核心概念对比

在这里插入图片描述
1.3 Elasticsearch-索引、文档、字段、映射—与 MySQL 的类比

如果把 MySQL 比作“关系型世界里的老管家”,那 Elasticsearch(后文简称 ES)就是“搜索界的自由派艺术家”。两者都能存数据、都能查数据,但底层哲学截然不同:MySQL 强调“先定结构,后放数据”;ES 则允许“边写边改结构”,甚至鼓励冗余与反范式。要快速把 MySQL 的经验迁移到 ES,最省脑细胞的法子就是“类比”——把熟悉的表、行、列、Schema 一一对应到 ES 的索引、文档、字段、映射。下面用一张“直译表”先给出结论,再逐条拆坑。

MySQL 概念ES 概念类比关系关键差异一句话
databasecluster1:N一个集群可挂 N 个索引,database 只是逻辑隔离
tableindex1:1index 相当于“一张大宽表”,但无 JOIN
rowdocument1:1document 就是 JSON,自带 _id 主键
columnfield1:1field 类型可嵌套、可多值,无需先 ALTER
schemamapping1:1mapping 只约束“倒排索引如何建”,不约束源码 JSON

1.3.1 索引 ≠ 数据库,却是“最大粒度”的隔离单元

很多人第一次 Kibana 建索引时,下意识把 index 当成 database,结果一个业务库建了十几个 index,shard 爆炸。
正确姿势:

  • 一个“业务实体”对应一个 index,比如 orderproduct
  • 如果日增量过 TB,再按时间滚动 (order-2025-10),而不是按字段分 index。
  • 集群级别设置(分片数、副本数)在 index 创建时固化,后续改=重建。

1.3.2 文档 = 行 + 超能力

MySQL 的行是“定长结构”,ES 的文档是“JSON 树”。
超能力 1:字段可以突然多出来

POST /user/_doc/1
{
  "name": "alice",
  "tags": ["coder", "coffee"]   // 之前 mapping 里没有 tags 也能写
}

超能力 2:数组原生支持,无需另建表。
超能力 3:嵌套对象(nested)/父子文档(join)模拟 1-N,但性能代价远高于 MySQL 的 JOIN,必须预评估。

1.3.3 字段类型:ES 的“动态猜” vs MySQL 的“先声明”

MySQL 的 VARCHAR(32) 一旦定死,插 abcdef 超长直接报错。
ES 第一次见新字段,会“动态映射”:

  • 字符串 → text + keyword 双字段
  • 整型 → long
  • 浮点 → float
  • 日期 → date(能解析才认)

生产环境务必关掉 dynamic: true,改为 strictruntime,否则某天有人塞了一个 ip 字段被识别成 text,聚合秒变噩梦。

1.3.4 Mapping:不是“锁结构”,而是“告诉 Lucene 怎么建倒排”

MySQL 的 DDL 一旦执行,表结构即刻硬化;ES 的 mapping 只影响“索引阶段”的倒排生成,已经存进去的文档不会被动迁。
典型坑:

  • 想把 statustext 改成 keyword 做聚合?需要 reindex。
  • 想加子字段 title.keyword?可以用 PUT mapping 追加,但老数据不会自动回填,需要 _update_by_query
  • enabled: false 的字段会完整存 _source 但不建倒排,相当于 MySQL 的“不建索引”。

1.3.5 主键:_id 与业务主键的博弈

MySQL 用 INT PKUUID;ES 用 _id 字符串。
最佳实践:

  • 如果业务本身有唯一键 order_no,直接拿它当 _id,省去二次映射。
  • 高并发写入时,让 ES 自生成 _id 比指定 _id 快 2~3 倍(少了版本冲突检查)。
  • _id 唯一性只在单 index 内保证,跨 index 可重复。

1.3.6 事务:没有 ACID,只有“单文档原子”

MySQL 的 BEGIN/COMMIT 可以跨多行;ES 的 bulk 只是“批打包”,其中任一文档失败不影响其他。
需要“事务级”一致性?只能客户端二次校验或走“版本号 + 乐观锁”套路:

PUT /account/_doc/1?if_seq_no=1024&if_primary_term=3
{ "balance": 900 }

失败返回 409 Conflict,业务层重试。

1.3.7 聚合:GROUP BY 的“光速版”与“内存杀手”

MySQL 的 GROUP BY 走 B+Tree 或临时文件;ES 的 terms agg 直接读倒排,亿级行毫秒回。
代价:

  • 聚合结果默认“近似”,shard_size 太小会丢桶。
  • 高基数字段(如 user_id 千万级)做全聚合,Fielddata 会把内存打爆,需要 cardinalitycomposite agg 分页。

1.3.8 小结:一张脑图带走

MySQL world          →        Elasticsearch world
database             →        cluster(逻辑隔离最小单元)
table                →        index(分片在集群层)
row                  →        document(JSON,_id 主键)
column               →        field(可嵌套、可多值)
schema DDL           →        mapping(只约束倒排,可追加)
JOIN                 →        nested / join / 宽表冗余
GROUP BY             →        agg(近实时、内存敏感)
ACID                 →        单文档原子 + 乐观锁

记住一句话:
“索引像表,文档像行,字段像列,映射像 Schema,但别被类比绑架——ES 是搜索引擎,不是另一个 MySQL。”
更多技术文章见公众号: 大城市小农民

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乔丹搞IT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值