3、数据模型设计:批次主数据模型、事件日志模型、关系图谱模型(DAG)

批次谱系查询的核心挑战在于:数据分散在多个异构系统(MES、WMS、QMS、ERP),且追溯链路需要支持双向(前向/后向)快速检索。为解决这一问题,我们设计了三个相互关联的数据模型层:批次主数据模型(静态属性)、事件日志模型(动态行为)、关系图谱模型(拓扑结构)。三者共同构成了跨系统追溯的“数据底座”。

3.1 批次主数据模型

批次主数据是追溯的“锚点”,记录每个批次从创建到完结的静态与半静态属性。该模型通常存储在关系型数据库(如 PostgreSQL、MySQL)或分布式 KV 存储(如 HBase)中,以批次 ID 作为全局唯一键。

字段 类型 说明 示例
batch_id VARCHAR(64) 全局唯一批次编码(含工厂/产线前缀) CN-SH-20250321-A001
material_code VARCHAR(32) 物料编码 MTR-8801-01
batch_type INT 1=生产批次, 2=原料批次, 3=半成品批次, 4=成品批次 1
quantity DECIMAL(18,3) 批次数量(单位由物料主数据定义) 5000.000
status INT 0=创建, 1=在制, 2=完成, 3=冻结, 4=报废 2
produce_date DATETIME 生产日期 2025-03-21 08:00:00
expire_date DATETIME 有效期(仅成品/原料批次) 2025-09-21 23:59:59
source_system VARCHAR(16) 数据来源系统标识 MES
attributes JSON 扩展属性(如供应商批次号、生产线、班次) {"line":"L03","shift":"A"}
设计要点:批次主数据应尽量“轻量”,仅保留高频查询的静态字段。大量动态属性(如质检结果、工艺参数)建议通过事件日志模型关联,避免主表过宽导致写入性能下降。

3.2 事件日志模型

事件日志模型记录批次在其生命周期中发生的每一次“状态变更”或“业务动作”。它是追溯链路的“时序证据链”,也是后续构建关系图谱的原始数据源。该模型通常采用追加写的时序表或消息队列(如 Kafka)持久化。

-- 事件日志表核心结构(DDL 示例)
CREATE TABLE batch_event_log (
    event_id        BIGINT AUTO_INCREMENT PRIMARY KEY,
    batch_id        VARCHAR(64)     NOT NULL,
    event_type      VARCHAR(32)     NOT NULL COMMENT '事件类型:RECEIVE/CONSUME/SPLIT/MERGE/QC_PASS/QC_FAIL',
    source_system   VARCHAR(16)     NOT NULL,
    target_batch_id VARCHAR(64)     DEFAULT NULL COMMENT '关联批次(拆分/合并时使用)',
    operator        VARCHAR(32)     DEFAULT NULL,
    event_time      DATETIME(3)     NOT NULL,
    payload         JSON            DEFAULT NULL COMMENT '事件载荷(如数量、工单号、设备ID)',
    INDEX idx_batch_time (batch_id, event_time),
    INDEX idx_event_type (event_type)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
事件类型 触发场景 关键载荷字段
RECEIVE 原料入库、半成品接收 供应商批次、收货数量
CONSUME 投料消耗(批次被使用) 消耗数量、工单号
SPLIT 批次拆分(如分装) 子批次列表、拆分比例
MERGE 批次合并(如混批) 源批次列表、合并后数量
QC_PASS / QC_FAIL 质检放行/不合格 检验单号、不合格代码
避坑提示:事件日志的 event_time 应使用业务时间(而非系统入库时间),避免因消息队列积压导致时序错乱。同时,建议对 target_batch_id 建立独立索引,以支持反向追溯(从子批次找父批次)。

3.3 关系图谱模型(DAG)

关系图谱模型将事件日志中的“批次间关联”抽象为有向无环图(DAG)。每个批次是一个节点,批次间的“消耗/产出”、“拆分/合并”关系构成有向边。该模型是快速追溯查询的核心——它避免了每次查询都扫描全量事件日志,而是通过预计算或物化路径实现毫秒级链路检索。

核心设计思路:将“事件”转化为“边”,将“批次”转化为“节点”,用图结构存储批次间的依赖关系。支持双向遍历:从原料查成品(前向),从成品查原料(后向)。
批次关系图谱模型(DAG)结构 原料批次 A 原料批次 B 半成品批次 C 成品批次 D 成品批次 E 拆分批次 F 原料批次 半成品批次 成品批次 拆分批次 拆分关系

3.4 三种模型的协同关系

三个模型并非孤立存在,而是形成“主数据 → 事件日志 → 关系图谱”的逐层抽象与派生关系。下图展示了数据流转与查询路径:

三层模型协同架构 批次主数据模型 静态属性 · 唯一标识 事件日志模型 时序行为 · 原始证据 关系图谱模型 DAG拓扑 · 快速追溯 查询路径说明 1. 用户输入批次 ID → 查询主数据模型获取批次属性 2. 根据主数据中的批次类型,从关系图谱模型获取上下游节点(毫秒级) 3. 如需事件详情(如质检结果),再回查事件日志模型获取原始载荷

3.5 模型选型与存储策略

模型 推荐存储 查询模式 数据量级 一致性要求
批次主数据 关系型数据库(MySQL/PostgreSQL)或 TiDB 点查(by batch_id)、范围查(by date/status) 百万~千万级 强一致(ACID)
事件日志 时序数据库(InfluxDB/TimescaleDB)或 Kafka + 对象存储 按批次ID+时间范围扫描 亿级~百亿级 最终一致(允许少量乱序)
关系图谱 图数据库(Neo4j/JanusGraph)或 关系型+物化路径 图遍历(BFS/DFS)、路径查询 千万~十亿级边 最终一致(异步构建)
实践建议:对于中小规模场景(日增批次 < 10万),关系图谱可直接使用关系型数据库的“物化路径”方案(如存储每个批次的祖先路径字符串),避免引入图数据库带来的运维复杂度。大规模场景下,推荐使用 JanusGraph 或 Neo4j 以支持深度递归查询。