3. 发酵批次数据结构化与数据库构建

发酵过程的数据天然是“多源、异步、多粒度”的:DCS/SCADA 以秒或分钟级持续记录温度、pH、溶氧、搅拌转速、补料重量等在线信号;化验室隔几小时才给出菌体浓度、产物效价、残糖、氨基氮等离线检测值;工艺员则在批记录上记下接种、补料策略切换、pH 异常调节、染菌报警、放罐等事件。如果这三类数据各自躺在不同文件里,建模时最耗时的往往不是算法,而是“把某一批第 37 小时的效价和当时的溶氧对上”。本节要解决的就是把批次运行数据、离线检测数据与工艺事件记录组织成可追溯、可查询、可建模的批次数据表与元数据体系。

一、批次数据模型的三个层次

结构化不是简单地把 Excel 拼在一起,而是先确定数据模型的层次。推荐采用“批次主表—时序事实表—事件表”的三层结构:

  • 批次主表(batch):一行代表一个批次,存放批次号、产品/菌种、发酵罐编号、种子批号、接种时间、放罐时间、批状态、最终效价等批次级属性,是全部数据的锚点。
  • 时序事实表(timeseries):一行代表“某批次某变量某时刻的一个值”,核心字段为 batch_id、tag_code、ts、value、quality。在线信号与离线检测统一进这张表,用 source 字段区分 online/lab,用 quality 字段标记好值、坏值、人工录入。
  • 事件表(event):一行代表一次工艺事件,字段包括 batch_id、event_time、event_type、operator、detail。补料切换、pH 调节、取样、报警、放罐都进这张表。

三层之间通过 batch_id 关联,时间字段统一为带时区的时间戳,这是后续做时间对齐和特征工程的基础。

二、元数据体系:让字段“自解释”

只有表结构还不够,必须配套元数据,否则半年后没人说得清 tag FERM01_DO 的单位是 % 还是 mg/L。元数据至少包含三部分:

  • 变量字典:tag_code、中文名、单位、数据类型、量程、采样周期、来源系统、是否关键变量。
  • 批次属性字典:批状态取值(运行/正常结束/异常终止)、异常原因编码、产品规格。
  • 事件类型字典:event_type 的枚举值与含义,保证不同工艺员记录同一事件时用词一致。
元数据建议以独立的字典表维护,而不是写死在程序里。新增一个变量或事件类型时只改字典表,历史数据的可读性不受影响。

三、从原始数据到入库的关键处理

以某 50 L 发酵罐一个批次(示例批次号 FB2024-018,示例数据)为例,说明入库流程中的关键动作:

  1. 批次对齐:把接种时刻定义为批次相对时间 t=0,所有时序与事件都换算为“相对接种小时数”,避免不同批次因绝对时间不同而无法叠加比较。
  2. 时间戳规范化:统一为 ISO 8601 带时区格式,消除 DCS 本地时间与化验室录入时间不一致的问题。
  3. 离线数据挂接:化验单上的“取样时间”作为 ts,检测值作为 value,source 标为 lab。注意取样时间与出结果时间不同,建模应以取样时间为准。
  4. 质量标记:对超出量程、长时间不变(死值)、通信中断区间的点标为 bad,保留原始值不删除,保证可追溯。
  5. 事件编码:把自由文本事件映射到字典中的 event_type,例如“补加葡萄糖”映射为 FEED_SWITCH。

下面这段示例 SQL 展示了时序事实表的核心建表与一次典型查询,可作为建库起点:

CREATE TABLE timeseries (
  batch_id   VARCHAR(32) NOT NULL,
  tag_code   VARCHAR(64) NOT NULL,
  ts         TIMESTAMPTZ NOT NULL,
  value      DOUBLE PRECISION,
  quality    SMALLINT DEFAULT 0,   -- 0好 1可疑 2坏
  source     VARCHAR(8)  NOT NULL, -- online / lab
  PRIMARY KEY (batch_id, tag_code, ts)
);

-- 查询某批次关键变量在 20~40 相对小时的数据
SELECT tag_code, ts, value
FROM timeseries
WHERE batch_id = 'FB2024-018'
  AND tag_code IN ('DO','pH','FEED_WT')
  AND ts BETWEEN '2024-05-11 08:00+08' AND '2024-05-12 04:00+08'
  AND quality = 0
ORDER BY tag_code, ts;

四、可追溯与可查询的落地要点

可追溯意味着任何一个建模用的数值都能回答“它从哪来、经过什么处理”。实践中建议保留原始层(raw)、清洗层(clean)和特征层(feature)三套数据,清洗规则版本化记录。可查询则要求为 batch_id、tag_code、ts 建立合适索引,并把常用查询封装为视图,例如“批次关键变量宽表视图”,让建模人员不必每次手写多表关联。

发酵批次数据三层结构与元数据体系 在线运行数据 DCS/SCADA 秒~分钟级 离线检测数据 化验室 小时级 工艺事件记录 批记录/操作日志 批次主表 batch batch_id · 罐号 · 接种/放罐时间 时序事实表 timeseries batch_id · tag_code · ts value · quality · source 事件表 event batch_id · event_time · event_type 1 : N 1 : N 元数据字典 变量字典 tag_code · 单位 · 量程 采样周期 · 来源系统 批次属性字典 批状态 · 异常原因编码 事件类型字典 event_type 枚举与含义 保证字段自解释、口径一致 数据分层: raw 原始层 → clean 清洗层 → feature 特征层 规则版本化

五、一个可直接参考的批次数据表字段清单

下表给出三层表的核心字段示例,可作为建库时的起点,字段可按实际工艺增删:

表核心字段说明
batchbatch_id, product, strain, fermenter_no, seed_lot, inoc_time, harvest_time, status, final_titer批次锚点,一行一批
timeseriesbatch_id, tag_code, ts, value, quality, source在线与离线统一存放
eventbatch_id, event_time, event_type, operator, detail工艺事件,event_type 受字典约束
tag_dicttag_code, name_cn, unit, range_min, range_max, sample_period, source_system变量字典

六、常见问题与判断依据

建库过程中最容易出问题的是时间对齐和离线数据挂接。判断是否做对,可以用一个简单检查:随机抽 3 个批次,任取一个离线效价点,能否在 1 分钟内查到它对应的相对接种时间、当时的溶氧与 pH 值、以及该时段内发生的补料事件。如果查不到,说明关联键或时间基准还有问题。另一个检查是“同一变量同一时刻是否只有一条有效记录”,若出现重复,通常是 DCS 重传或人工补录未去重,需要在清洗层处理并记录规则版本。

不要为了“干净”而删除坏值或异常批次。发酵异常批次恰恰是趋势预测和故障识别最有价值的样本,应通过 quality 字段和批状态标记保留,而不是物理删除。

完成上述结构化后,后续的缺失值处理、时间对齐、滑动窗口特征提取才有稳定的输入。数据表与元数据体系一旦建立,建模工作就从“找数据”转向“用数据”,这也是发酵过程数据建模能够规模化的前提。