4. 工时数据模型与数据库设计
在食品MES中,人员工时统计的准确性并不取决于报表做得多漂亮,而取决于底层数据模型能否把“谁、在哪个班次、为哪张工单、在哪道工序、干了多长时间”这五件事稳定地关联起来。本节围绕人员、班次、工序、工单、工时记录五类核心实体,讲清它们之间的关系设计,并给出一套可直接参考的表结构与关键字段说明。
一、核心实体与关系判断
先明确各实体的职责边界。人员是工时归属主体,班次是时间口径,工序是作业内容口径,工单是任务来源口径,工时记录则是把前四者“钉”在一起的事实表。设计时最容易出错的地方,是把班次信息直接冗余进人员表,或把工序名称直接写进工时记录。前者导致人员换班后历史数据被覆盖,后者导致工序改名后统计口径断裂。
正确的关系是:人员与班次之间是多对多关系,通过“排班记录”关联,因为同一员工在不同日期可能上早班、中班或夜班;工单与工序是一对多关系,一张工单通常包含多道工序;工时记录作为事实表,同时引用人员、排班、工单、工序四个维度,并记录开始时间、结束时间、有效工时等度量。下图展示了这一关系结构。
二、工时记录表的关键字段设计
工时记录表是整个模型的事实核心,字段设计要同时满足“可追溯”和“可统计”两个目标。以下是一份参考表结构,字段命名采用常见MES习惯,实际项目可按数据库规范调整。
CREATE TABLE work_hour_record (
record_id BIGINT PRIMARY KEY,
emp_id VARCHAR(20) NOT NULL, -- 人员编号
schedule_id BIGINT NOT NULL, -- 排班记录,锁定班次口径
order_id VARCHAR(30) NOT NULL, -- 工单号
process_id VARCHAR(30) NOT NULL, -- 工序编号
start_time DATETIME NOT NULL, -- 实际开始时间
end_time DATETIME NOT NULL, -- 实际结束时间
break_minutes INT DEFAULT 0, -- 班中休息扣除分钟
valid_hours DECIMAL(6,2), -- 有效工时(小时)
record_type TINYINT, -- 1正常 2加班 3返工
source TINYINT, -- 1扫码 2手工补录
confirm_status TINYINT DEFAULT 0, -- 0待确认 1已确认
remark VARCHAR(200)
);
几个字段值得单独说明。schedule_id 而不是直接存 shift_id,是为了让工时记录绑定到“某人在某天上了哪个班”这一具体排班事实,避免跨天夜班在统计时归属错误。valid_hours 建议由系统按 end_time 减 start_time 再扣除 break_minutes 计算后落库,而不是每次报表实时算,这样历史数据不会因规则调整而漂移。record_type 用于区分正常工时、加班和返工工时,食品行业返工场景较多,单独标识后便于质量成本分析。source 与 confirm_status 则服务于数据可信度管理,手工补录的记录应进入待确认状态,由班组长审核后才计入正式统计。
三、食品行业的特殊约束
食品MES与离散制造的一个显著差异,是人员进出洁净区、更衣、洗手消毒等非直接作业时间也需要纳入工时口径管理。实践中通常把这类时间作为“辅助工时”单独记录,在工序表中设置一个虚拟工序(如“更衣消毒”),其标准工时按制度给定。这样既不影响直接工时的统计,又能完整反映人员在岗时间。
另一个约束是批次追溯。食品工单往往对应具体批次,工时记录若只关联工单而不关联批次,出现质量问题时难以快速定位“哪批产品由哪些人在什么时段生产”。建议在工时记录中增加 batch_no 字段,或在工单表中维护批次与工单的对应关系,通过关联查询实现追溯。此外,跨天夜班的起止时间可能落在两个自然日,统计日产量工时时应以班次归属日期为准,而非记录的开始日期,这一点必须在数据字典中写清楚,避免报表口径不一致。
四、从模型到统计的落地
模型设计完成后,常见的统计需求可以直接由 SQL 聚合得到。例如统计某员工某月的有效工时,按 record_type 分组求和即可;统计某工单各工序的实际工时与标准工时偏差,则将工时记录按 process_id 汇总后与工序表的标准工时对比。需要强调的是,所有统计都应基于 confirm_status = 1 的记录,待确认数据只用于过程监控,不进入考核口径。这样一套“维度清晰、事实唯一、口径可追溯”的模型,才能支撑后续的工时分析、效率评估与成本核算。