4. 看板数据模型与实时计算

看板要“实时”,靠的不是把数据库里的原始表直接刷到屏幕上,而是先把生产现场的数据组织成一套可计算、可聚合、可追溯的模型。车间运行中心看板的数据模型,核心是围绕“生产状态”这一分析主题,把班次、工单、工序、设备、人员、物料等对象拆成维度表,把每一次状态变化、产出、停机、报警记录成事实表,再在事实表之上定义实时指标的计算口径。这样,看板上的每一个数字都能回答三个问题:它来自哪条记录、按什么口径算出来、随时间如何变化。

一、事实表:记录“发生了什么”

事实表是看板的“事实底座”,它不存储描述性文字,而是存储可累加、可计数、可求平均的度量值,以及指向各维度表的外键。面向生产状态看板,最核心的事实表是设备状态事实表和工单工序产出事实表。

设备状态事实表记录设备每一次状态切换:设备ID、状态编码(运行、待机、故障、换型、保养)、开始时间、结束时间、持续秒数、所属班次ID、关联工单ID。它的粒度是“一次状态区间”,而不是“一分钟一条”。例如某台CNC在08:00:00进入运行,08:42:15因换刀停机,则产生一条运行区间记录,持续2535秒;停机后再产生一条待机或换型区间。这种“区间事实”比定时采样更省存储,也更容易计算OEE中的时间开动率。

工单工序产出事实表记录每个工单在每道工序上的产出与质量数据:工单ID、工序ID、设备ID、班次ID、合格数、不合格数、报废数、标准工时、实际工时、报工时间。它的粒度是“工单×工序×班次”的一次报工事件。当同一工单跨班次生产时,会按班次拆成多条记录,保证班次维度可独立汇总。

二、维度表:定义“按什么看”

维度表是看板的“观察角度”。没有维度表,事实表只是一堆数字;有了维度表,才能按班次、工单、工序、设备、产线、产品等任意组合下钻。

  • 班次维度:班次ID、班次名称(早班/中班/夜班)、计划开始时间、计划结束时间、跨天标志、所属工厂日历。跨天标志很关键,夜班从22:00到次日06:00,若不做跨天处理,按自然日汇总会把一个班次拆成两天。
  • 工单维度:工单号、产品编码、计划数量、计划开始/结束时间、工单状态(待产、在产、完工、关闭)、优先级。
  • 工序维度:工序ID、工序名称、工序顺序、标准节拍、所属工艺路线。
  • 设备维度:设备ID、设备名称、设备类型、所属产线、所属车间、设备等级。
  • 时间维度:以分钟或秒为最小粒度的时间戳、小时、班次、日、周、月,用于趋势图和时间切片。

维度表之间不是孤立的。工单通过工艺路线关联到多道工序,工序再绑定到可执行设备,设备又归属产线和车间。看板上的“某产线当前在产工单的工序进度”,就是沿着“产线→设备→工序→工单”这条维度链聚合出来的。

生产状态看板数据模型:维度表 → 事实表 → 实时指标 维度表(观察角度) 班次维度 班次ID / 跨天标志 / 计划时段 工单维度 工单号 / 产品 / 计划数量 / 状态 工序维度 工序ID / 顺序 / 标准节拍 设备维度 设备ID / 类型 / 产线 / 车间 时间维度 秒/分/时/班次/日/周/月 人员/物料维度 操作员 / 班组 / 物料批次 事实表(发生了什么) 设备状态事实表 设备ID(FK) 状态编码:运行/待机/故障/换型 开始时间 / 结束时间 持续秒数(度量) 班次ID(FK)/ 工单ID(FK) 工单工序产出事实表 工单ID(FK)/ 工序ID(FK) 设备ID(FK)/ 班次ID(FK) 合格数 / 不合格数 / 报废数 标准工时 / 实际工时 报工时间(时间戳) 报警/停机事件事实表 报警码 / 开始时间 / 恢复时间 / 影响时长 实时指标(算什么) 设备综合效率 OEE 时间开动率 × 性能开动率 × 合格率 按设备/产线/班次聚合 工单达成率 实际合格产出 ÷ 计划数量 按工单/产品/班次聚合 工序在制品 WIP 已报工未流转数量 按工序/产线实时快照 设备实时状态占比 运行/待机/故障时长占比 滑动窗口 15 分钟 报警响应时长 恢复时间 − 开始时间 关联 聚合

三、实时指标的计算逻辑

看板上的指标不是查出来就完事,必须定义清楚计算口径和刷新方式。以OEE为例,它由三个因子相乘:时间开动率 = 实际运行时间 ÷ 计划生产时间;性能开动率 = (理论节拍 × 实际产量)÷ 实际运行时间;合格率 = 合格数 ÷ 总产出数。这三个因子分别来自设备状态事实表(运行时长)、工单工序产出事实表(产量、节拍)和班次维度(计划生产时间)。

实时计算通常采用“流式聚合 + 滑动窗口”的方式。设备状态事实表每产生一条新记录,就触发一次增量更新:把该设备当前班次内的运行秒数累加,重新计算时间开动率;同时用最近15分钟的产出记录计算瞬时性能开动率。这样看板上的OEE不是等班次结束才算,而是每来一条状态变化或报工记录就刷新一次。

工单达成率的计算要注意“计划数量”的口径。如果工单跨班次,计划数量应按班次计划拆分,而不是把整单计划量压到当前班次。例如工单计划1000件,早班计划400件、中班计划350件、夜班计划250件,则早班达成率 = 早班合格数 ÷ 400。拆分依据可以来自排产系统的班次计划表,也可以按标准节拍和班次可用时间反推。

四、关联关系的处理要点

班次、工单、工序、设备四者之间的关联,是数据模型最容易出错的地方。第一,时间对齐:设备状态区间的开始和结束时间必须落在同一个班次内,跨班次的状态区间要在班次边界处切开,分别归属两个班次。第二,工单切换:同一台设备在一个班次内可能生产多个工单,产出事实表要按工单分别记录,不能合并。第三,工序与设备的绑定:一道工序可能由多台设备并行加工,产出事实表要记录实际加工设备ID,否则无法按设备下钻。第四,迟到数据:现场报工可能延迟几分钟到几十分钟,实时计算要允许滑动窗口回撤重算,避免看板数字“跳变”后不修正。

建议在事实表中统一使用“事件时间”而非“入库时间”作为时间戳,并在ETL层保留原始事件时间。这样即使数据延迟到达,也能按正确的时间窗口重新聚合,保证班次和工单维度的汇总结果一致。

五、一个可落地的建表示例

以下给出设备状态事实表与班次维度的简化建表语句,字段命名和类型可根据实际数据库调整。示例中状态编码用枚举值,持续秒数由应用层或数据库计算列生成。

-- 班次维度表
CREATE TABLE dim_shift (
  shift_id        INT PRIMARY KEY,
  shift_name      VARCHAR(20),      -- 早班/中班/夜班
  plan_start      TIME,             -- 计划开始时间
  plan_end        TIME,             -- 计划结束时间
  cross_day       TINYINT,          -- 1=跨天,0=不跨天
  calendar_id     INT               -- 关联工厂日历
);

-- 设备状态事实表
CREATE TABLE fact_equipment_status (
  status_id       BIGINT PRIMARY KEY,
  equipment_id    INT,              -- FK → dim_equipment
  shift_id        INT,              -- FK → dim_shift
  work_order_id   INT,              -- FK → dim_work_order,可为空
  status_code     VARCHAR(10),      -- RUN/IDLE/FAULT/CHANGEOVER/PM
  start_time      DATETIME,         -- 事件时间
  end_time        DATETIME,
  duration_sec    INT,              -- 持续秒数
  INDEX idx_eq_time (equipment_id, start_time),
  INDEX idx_shift (shift_id)
);

建表之后,实时指标可以用物化视图或流处理任务持续更新。例如每5秒扫描一次最近15分钟的状态区间,按设备分组汇总各状态时长,写入看板缓存表。看板前端只读缓存表,避免每次刷新都扫描全量事实表。这样既保证了实时性,也把计算压力从查询侧转移到了写入侧。

数据模型建得好不好,最终看三个检验:能不能按任意维度组合下钻、能不能在秒级刷新指标、能不能追溯到每一条原始记录。做到这三点,看板上的数字才真正可信、可用。