3. 批次记录的数据模型设计
批次生产记录的本质,是把“一次真实发生的生产”用结构化数据固定下来。要让MES既能记录、又能追溯、还能支撑报表与合规审计,就必须先设计好数据模型。本节围绕四类核心对象展开:批次主数据(物料、配方、工艺路线)、批次对象(Batch/Lot)、批次属性(状态、数量、单位、时间戳)以及关联关系(批次—工单—工序—物料),并用ER图与UML类图两种视角表达。
一、先分清主数据与批次实例
很多项目在建模初期把“配方”和“实际投料”混在一张表里,导致同一物料在不同批次间无法比较。正确做法是分层:主数据层描述“应该怎么做”,相对稳定、可版本化;批次实例层描述“实际怎么做的”,一次生产一条记录,不可随意修改。
主数据层包含三个关键实体。物料(Material):以物料编码为主键,记录名称、规格、基本计量单位、物料类型(原料/辅料/半成品/成品/包材)。配方(Recipe):挂在某个产出物料下,包含版本号、生效日期、批次规模(如1000 kg),以及配方行(物料、理论用量、单位、投料顺序、允差)。工艺路线(Routing):由若干工序(Operation)按顺序组成,每道工序定义工序号、工序名称、工作中心、标准工时、关键工艺参数(如杀菌温度85 ℃、保温15 min)。
这里有一个容易被忽略的细节:配方与工艺路线都应带版本。批次记录必须引用“当时生效的版本”,而不是“当前最新版本”。否则三年后回查某批产品,会发现配方已被改过,追溯链断裂。实践中常用“配方版本 + 工艺路线版本”双版本号锁定批次。
二、批次对象与批次属性
批次对象(Batch/Lot)是数据模型的核心。Batch通常指一次生产投料形成的批次,Lot常用于物料收货或分装形成的批号,二者在MES中可统一为“批次实体”,用批次类型字段区分(生产批/收货批/返工批)。批次主键建议采用“批次号”业务主键加内部自增ID,批次号按规则生成,例如 P20250612-001,便于人工识别。
批次属性决定记录的可追溯性,至少应包含:
- 状态:如“已创建→已下达→生产中→待检验→已放行/已冻结”,状态迁移必须有时间戳和操作人;
- 数量与单位:计划数量、实际产出数量、报废数量,单位统一到基本计量单位,展示单位可另设换算系数;
- 时间戳:计划开始/结束、实际开始/结束、各工序起止时间,统一用带时区的ISO 8601格式存储;
- 关联键:工单号、配方版本、工艺路线版本、产线/工作中心。
状态字段是合规审计的高频检查点。建议把状态设计为受控枚举,并单独建一张“批次状态变更日志”表,记录 from_state、to_state、变更时间、操作人、原因。这样既能还原批次生命周期,也能在出现质量异常时定位“在哪一步、谁、何时”改变了状态。
三、关联关系:批次—工单—工序—物料
四类关联构成追溯骨架:工单是生产指令,一个工单可产出多个批次(如一个工单分多锅生产),因此工单与批次是1:N;批次与工序是1:N,每个批次按工艺路线生成工序记录,记录实际参数;批次与物料通过“批次投料记录”形成M:N关系,记录投入了哪些物料批号、多少数量、来自哪个供应商批;同时产出物料也形成“批次产出记录”。这条链让“从成品批号反查原料批号”成为可能,也是召回演练的基础。
下图用ER视角表达实体与基数关系,用类图视角表达批次对象的属性与方法,二者互补:ER图回答“谁和谁有关系、几对几”,类图回答“对象有哪些字段、能执行哪些操作”。
四、落地时的关键设计决策
第一,数量字段要区分“计划/实际/报废”,并统一存储基本单位。例如配方批量1000 kg,实际投料主料998.5 kg、辅料12.3 kg,单位全部换算为kg存储,展示层再按需显示g或t。第二,时间戳统一带时区,避免跨厂区、跨时区追溯时出现“工序结束早于开始”的假象。第三,批次号与工单号解耦:一个工单可拆多批,批次号独立生成,工单号作为外键关联,便于按工单汇总、按批次追溯。
第四,关联表要带“角色”字段。批次与物料批的关系不是简单多对多,而是“投入”或“产出”,甚至同一物料批可能先投入后剩余退回。建议在关联表中增加 role(投入/产出/退回)、数量、单位、时间戳,使关系本身也成为可审计的记录。第五,版本引用要快照化:批次记录中除存 recipeVersion 外,建议冗余存储关键配方行与工艺参数的实际值,防止主数据后续修改影响历史批次的可读性。
最后提醒一个常见误区:不要把“批次状态”和“质量检验状态”混为一个字段。生产状态(生产中/已完工)与质量状态(待检/合格/不合格/冻结)是两个维度,合并后会导致“已完工但不合格”这类组合无法表达。分开建模,再用放行规则组合判断,模型才既简洁又经得起审计。