2. 工单数据模型设计
工单数据模型是生产执行系统(MES)中最核心的数据骨架。它决定了工单能否被正确下达、能否被准确派工、能否被追溯。很多项目在实施初期只建了一张“工单表”,把物料、工艺、工序信息全部塞进备注字段,结果在派工、报工、追溯环节反复返工。本节从实体关系出发,给出可直接落地的表结构设计。
一、先理清四个核心实体的关系
工单数据模型围绕四个实体展开:工单主数据(Work Order)、物料清单(BOM)、工艺路线(Routing)、工序与工步(Operation / Step)。它们的关系不是简单的树形,而是“工单引用版本化的BOM与工艺路线,工艺路线下挂工序,工序下挂工步”的引用关系。
关键设计原则有三条:
- 版本化:BOM和工艺路线都必须带版本号,工单下达时冻结引用版本,避免工程变更(ECN)导致已下达工单“漂移”。
- 快照与引用分离:工单主数据保存对BOM版本、工艺路线版本的引用ID;同时可冗余关键字段(如物料编码、数量)作为快照,保证历史可追溯。
- 工序与工步分层:工序是派工和报工的最小单位,工步是工序内部的作业指导分解,不直接参与派工,但参与防错和追溯。
下图展示了四个实体之间的引用关系与关键字段归属,注意工单是“聚合根”,BOM和工艺路线通过版本被工单引用,工序与工步则从属于工艺路线。
二、工单主数据表设计
工单主数据表是聚合根,所有派工、报工、追溯都从这里出发。核心字段如下:
CREATE TABLE work_order (
wo_id BIGINT PRIMARY KEY AUTO_INCREMENT,
wo_no VARCHAR(32) NOT NULL UNIQUE, -- 工单号,如 WO-20250612-001
material_id BIGINT NOT NULL, -- 产出物料
plan_qty DECIMAL(12,3) NOT NULL, -- 计划数量
done_qty DECIMAL(12,3) DEFAULT 0, -- 已完工数量
bom_ver_id BIGINT NOT NULL, -- 冻结的BOM版本
routing_ver_id BIGINT NOT NULL, -- 冻结的工艺路线版本
plan_start DATETIME,
plan_end DATETIME,
status TINYINT DEFAULT 10, -- 10已创建 20已下达 30生产中 40已完工 50已关闭
priority TINYINT DEFAULT 5,
create_time DATETIME DEFAULT CURRENT_TIMESTAMP
);
注意 status 字段的取值设计:10=已创建、20=已下达、30=生产中、40=已完工、50=已关闭。派工操作只允许在 status=20 或 30 时进行,这是后续派工模块的硬约束。
三、BOM表设计:头行结构
BOM采用“头+行”结构。头表记录版本信息,行表记录父子物料关系。关键点是版本冻结:工单引用的是 bom_ver_id,而不是物料ID。
CREATE TABLE bom_header (
bom_ver_id BIGINT PRIMARY KEY AUTO_INCREMENT,
material_id BIGINT NOT NULL,
version VARCHAR(16) NOT NULL, -- 如 V1.0
status TINYINT DEFAULT 1, -- 1草稿 2已发布 3已冻结
effective_date DATE,
UNIQUE KEY uk_mat_ver (material_id, version)
);
CREATE TABLE bom_line (
line_id BIGINT PRIMARY KEY AUTO_INCREMENT,
bom_ver_id BIGINT NOT NULL,
child_material_id BIGINT NOT NULL,
qty_per DECIMAL(12,6) NOT NULL, -- 单位用量
scrap_rate DECIMAL(6,4) DEFAULT 0, -- 损耗率,如0.02
seq_no INT DEFAULT 1,
FOREIGN KEY (bom_ver_id) REFERENCES bom_header(bom_ver_id)
);
教学示例:生产100台电机(WO-20250612-001),BOM行中定子用量1.0、转子用量1.0、端盖用量2.0、损耗率0.02。则端盖的毛需求 = 100 × 2.0 × (1+0.02) = 204件。这个计算在派工时用于齐套检查。
四、工艺路线、工序与工步表设计
工艺路线头表与BOM头表类似,也带版本。工序表挂在路线版本下,工步表挂在工序下。
CREATE TABLE routing_header (
routing_ver_id BIGINT PRIMARY KEY AUTO_INCREMENT,
material_id BIGINT NOT NULL,
version VARCHAR(16) NOT NULL,
status TINYINT DEFAULT 1,
UNIQUE KEY uk_mat_ver (material_id, version)
);
CREATE TABLE routing_operation (
op_id BIGINT PRIMARY KEY AUTO_INCREMENT,
routing_ver_id BIGINT NOT NULL,
op_seq INT NOT NULL, -- 工序号 10,20,30
op_name VARCHAR(64), -- 如 绕线、装配、测试
workcenter_id BIGINT, -- 默认工位
std_time_min DECIMAL(8,2), -- 标准工时(分钟)
FOREIGN KEY (routing_ver_id) REFERENCES routing_header(routing_ver_id)
);
CREATE TABLE operation_step (
step_id BIGINT PRIMARY KEY AUTO_INCREMENT,
op_id BIGINT NOT NULL,
step_seq INT NOT NULL,
step_desc VARCHAR(255), -- 作业指导
check_point VARCHAR(128), -- 防错检查点
FOREIGN KEY (op_id) REFERENCES routing_operation(op_id)
);
以电机装配为例,工艺路线 V1.0 包含三道工序:10 绕线(工位 WC-01,标准工时 12min)、20 装配(工位 WC-02,18min)、30 测试(工位 WC-03,8min)。工序20下挂三个工步:20.1 压装轴承、20.2 安装端盖、20.3 拧紧螺栓(扭矩检查点 12N·m)。派工时以工序为单位派到工位,工步作为作业指导展示给操作工。
五、实体关系与约束总结
| 关系 | 基数 | 约束说明 |
|---|---|---|
| 工单 → BOM版本 | N:1 | 下达时冻结,不可修改 |
| 工单 → 工艺路线版本 | N:1 | 下达时冻结,不可修改 |
| 工艺路线 → 工序 | 1:N | 按 op_seq 排序 |
| 工序 → 工步 | 1:N | 按 step_seq 排序 |
| BOM头 → BOM行 | 1:N | 按 seq_no 排序 |