ES-模型-索引文档与历史Type概念
定位:澄清 Elasticsearch 中最基本的存储单位和命名概念,避免被旧文档和错误示例误导,为后续索引设计和数据建模打下清晰心智模型。
大纲
- Index(索引):逻辑集合的含义
- Document(文档):JSON 为中心的数据模型
- _id、_source 等核心元字段
- Type 历史回顾:从多 Type 到单 Type
- 索引与业务建模的关系:一个索引放什么,不放什么
- 与传统数据库中「库 / 表 / 行」的类比与反类比
Todo 要点(查漏补缺清单)
1. Index(索引)
- 定义:索引是「一组结构相近文档的逻辑集合」,对应一个或多个底层分片。
- 区分:
- 索引名称(index name)应具有业务含义(如
logs-nginx-2025.11.09、products-v1)。 - 不要把完全不同结构的文档混进一个索引(增加复杂度和风险)。
- 索引名称(index name)应具有业务含义(如
- 说明:
- 一个索引在物理上会被拆成多个 shard。
- 应避免为每一个小租户/用户创建独立索引的反模式(索引数量爆炸)。
2. Document(文档)
- 定义:Document 是以 JSON 表示的一条记录,存储在索引中。
- 核心字段:
_id:文档主键,可自定义或由 ES 自动生成。_source:原始 JSON 内容,用于查询返回与重建。
- 提醒:
fields(倒排索引存储)和_source(原文)是两个层次。- 合理控制文档大小,避免超大 JSON 导致查询和更新成本过高。
3. 关于 _id 的实践注意点
- 说明使用自然业务 ID(如订单号、用户ID)的优缺点:
- 方便幂等写入和精确查询。
- 可能存在写入热点(需结合 routing 策略考虑)。
- 使用自动生成
_id的场景:- 日志/事件数据,写多读少,ID 不重要。
- 补充示例:基于
_id的更新 vs 基于文档内容的查询更新。
4. Type 历史回顾(避免旧教程坑)
- 解释旧版本概念:
- 早期 ES 支持一个索引中有多个 Type,类似「同一数据库中的多张表」。
- 说明演进:
- 从 6.x 开始废弃多 Type,7.x 之后基本只有
_doc。
- 从 6.x 开始废弃多 Type,7.x 之后基本只有
- 明确实践结论:
- 不要在设计中再使用多 Type 思想。
- 一个索引承载一种「文档类型」的心智模型即可。
- 标记:
- 阅读旧博客 / StackOverflow 答案时,看到 Type 相关内容要自动 mentally translate 为当前单 Type 模式。
5. 索引与业务建模关系
- 提出几个关键问题,帮助决策「要不要拆索引」:
- 文档结构是否接近?
- 查询模式是否相似(过滤条件、排序方式、时间范围)?
- 生命周期和保留策略是否一致?
- 常见模式:
- 按业务域拆索引(
orders-*、logs-*、metrics-*)。 - 按时间分索引(日志/埋点数据:
logs-YYYY.MM.DD)。
- 按业务域拆索引(
- 危险模式:
- 一个「大杂烩」索引装下各种无关数据。
- 为每个用户/租户单独建索引导致管理和资源失控。
- 留出 TODO:
- 在后续 ES-性能-索引与时间分区设计 和 ES-集群-节点角色与拓扑设计 中回链索引建模策略。
6. 类比与反类比(帮助建立正确直觉)
- 类比图(可在 Canvas 或 Excalidraw 中补画):
- 传统:Database → Table → Row。
- ES:Cluster → Index → Document。
- 反类比提醒:
- ES Index ≠ 关系型 Table(虽有相似之处,但有分片、倒排等差异)。
- Document 模型更灵活(嵌套、数组),要结合后续 Mapping 章节一起理解。
- 用 1-2 个你真实业务的例子:
- 订单系统:一个订单文档包含订单信息+行项目数组。
- 日志系统:一个日志文档包含时间戳、级别、服务名、消息体。