4. 看板数据模型与实时计算
看板要“实时”,靠的不是把数据库里的原始表直接刷到屏幕上,而是先把生产现场的数据组织成一套可计算、可聚合、可追溯的模型。车间运行中心看板的数据模型,核心是围绕“生产状态”这一分析主题,把班次、工单、工序、设备、人员、物料等对象拆成维度表,把每一次状态变化、产出、停机、报警记录成事实表,再在事实表之上定义实时指标的计算口径。这样,看板上的每一个数字都能回答三个问题:它来自哪条记录、按什么口径算出来、随时间如何变化。
一、事实表:记录“发生了什么”
事实表是看板的“事实底座”,它不存储描述性文字,而是存储可累加、可计数、可求平均的度量值,以及指向各维度表的外键。面向生产状态看板,最核心的事实表是设备状态事实表和工单工序产出事实表。
设备状态事实表记录设备每一次状态切换:设备ID、状态编码(运行、待机、故障、换型、保养)、开始时间、结束时间、持续秒数、所属班次ID、关联工单ID。它的粒度是“一次状态区间”,而不是“一分钟一条”。例如某台CNC在08:00:00进入运行,08:42:15因换刀停机,则产生一条运行区间记录,持续2535秒;停机后再产生一条待机或换型区间。这种“区间事实”比定时采样更省存储,也更容易计算OEE中的时间开动率。
工单工序产出事实表记录每个工单在每道工序上的产出与质量数据:工单ID、工序ID、设备ID、班次ID、合格数、不合格数、报废数、标准工时、实际工时、报工时间。它的粒度是“工单×工序×班次”的一次报工事件。当同一工单跨班次生产时,会按班次拆成多条记录,保证班次维度可独立汇总。
二、维度表:定义“按什么看”
维度表是看板的“观察角度”。没有维度表,事实表只是一堆数字;有了维度表,才能按班次、工单、工序、设备、产线、产品等任意组合下钻。
- 班次维度:班次ID、班次名称(早班/中班/夜班)、计划开始时间、计划结束时间、跨天标志、所属工厂日历。跨天标志很关键,夜班从22:00到次日06:00,若不做跨天处理,按自然日汇总会把一个班次拆成两天。
- 工单维度:工单号、产品编码、计划数量、计划开始/结束时间、工单状态(待产、在产、完工、关闭)、优先级。
- 工序维度:工序ID、工序名称、工序顺序、标准节拍、所属工艺路线。
- 设备维度:设备ID、设备名称、设备类型、所属产线、所属车间、设备等级。
- 时间维度:以分钟或秒为最小粒度的时间戳、小时、班次、日、周、月,用于趋势图和时间切片。
维度表之间不是孤立的。工单通过工艺路线关联到多道工序,工序再绑定到可执行设备,设备又归属产线和车间。看板上的“某产线当前在产工单的工序进度”,就是沿着“产线→设备→工序→工单”这条维度链聚合出来的。
三、实时指标的计算逻辑
看板上的指标不是查出来就完事,必须定义清楚计算口径和刷新方式。以OEE为例,它由三个因子相乘:时间开动率 = 实际运行时间 ÷ 计划生产时间;性能开动率 = (理论节拍 × 实际产量)÷ 实际运行时间;合格率 = 合格数 ÷ 总产出数。这三个因子分别来自设备状态事实表(运行时长)、工单工序产出事实表(产量、节拍)和班次维度(计划生产时间)。
实时计算通常采用“流式聚合 + 滑动窗口”的方式。设备状态事实表每产生一条新记录,就触发一次增量更新:把该设备当前班次内的运行秒数累加,重新计算时间开动率;同时用最近15分钟的产出记录计算瞬时性能开动率。这样看板上的OEE不是等班次结束才算,而是每来一条状态变化或报工记录就刷新一次。
工单达成率的计算要注意“计划数量”的口径。如果工单跨班次,计划数量应按班次计划拆分,而不是把整单计划量压到当前班次。例如工单计划1000件,早班计划400件、中班计划350件、夜班计划250件,则早班达成率 = 早班合格数 ÷ 400。拆分依据可以来自排产系统的班次计划表,也可以按标准节拍和班次可用时间反推。
四、关联关系的处理要点
班次、工单、工序、设备四者之间的关联,是数据模型最容易出错的地方。第一,时间对齐:设备状态区间的开始和结束时间必须落在同一个班次内,跨班次的状态区间要在班次边界处切开,分别归属两个班次。第二,工单切换:同一台设备在一个班次内可能生产多个工单,产出事实表要按工单分别记录,不能合并。第三,工序与设备的绑定:一道工序可能由多台设备并行加工,产出事实表要记录实际加工设备ID,否则无法按设备下钻。第四,迟到数据:现场报工可能延迟几分钟到几十分钟,实时计算要允许滑动窗口回撤重算,避免看板数字“跳变”后不修正。
五、一个可落地的建表示例
以下给出设备状态事实表与班次维度的简化建表语句,字段命名和类型可根据实际数据库调整。示例中状态编码用枚举值,持续秒数由应用层或数据库计算列生成。
-- 班次维度表
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分钟的状态区间,按设备分组汇总各状态时长,写入看板缓存表。看板前端只读缓存表,避免每次刷新都扫描全量事实表。这样既保证了实时性,也把计算压力从查询侧转移到了写入侧。
数据模型建得好不好,最终看三个检验:能不能按任意维度组合下钻、能不能在秒级刷新指标、能不能追溯到每一条原始记录。做到这三点,看板上的数字才真正可信、可用。