4. BOM数据模型
BOM(Bill of Materials,物料清单)是 MRP 运算的核心数据基础。一个设计良好的 BOM 数据模型,需要准确表达物料之间的父子层级关系、装配数量、时间有效性等关键维度。本章从数据库表结构设计出发,详细解析 BOM 的核心字段及其在 MRP 计算中的映射逻辑。
4.1 BOM 核心数据库表结构
在 ERP 系统中,BOM 通常采用“主表 + 子表”的经典设计模式。主表存储 BOM 头信息(如 BOM 编号、版本、生效日期),子表存储具体的物料组成明细(如子件物料、数量、工序)。
| 表名 | 说明 | 核心字段 |
|---|---|---|
| BOM_HEADER | BOM 主表,记录 BOM 版本、状态、有效期 | BOM_ID, ITEM_ID, BOM_NAME, VERSION, STATUS, EFF_DATE, EXP_DATE, CREATE_TIME |
| BOM_ITEM | BOM 子表,记录每个子件物料及用量 | BOM_ITEM_ID, BOM_ID, PARENT_ITEM_ID, CHILD_ITEM_ID, QUANTITY, SCRAP_PCT, OPS_SEQ, EFF_DATE, EXP_DATE |
| ITEM_MASTER | 物料主文件,存储物料基础属性 | ITEM_ID, ITEM_CODE, ITEM_NAME, UOM, ITEM_TYPE, LEAD_TIME, LOT_SIZE |
设计要点:BOM_ITEM 表中的 PARENT_ITEM_ID 和 CHILD_ITEM_ID 共同构成父子关系字段,通过这两个字段可以递归展开任意层级的 BOM 结构。建议在数据库层面为这两个字段建立联合索引,以加速 MRP 的递归查询性能。
4.2 父子关系字段与层级结构
BOM 的父子关系通过 PARENT_ITEM_ID 和 CHILD_ITEM_ID 两个字段实现。一个父物料可以包含多个子物料,一个子物料也可以被多个父物料使用(多父项)。这种设计天然支持树形结构的递归展开。
以下是一个典型的 BOM 层级展开 SQL 示例(使用递归 CTE):
WITH RECURSIVE BOM_EXPLOSION AS (
-- 根节点:查询顶层成品
SELECT
bi.BOM_ID,
bi.PARENT_ITEM_ID,
bi.CHILD_ITEM_ID,
bi.QUANTITY,
1 AS LEVEL,
CAST(bi.CHILD_ITEM_ID AS VARCHAR(500)) AS PATH
FROM BOM_ITEM bi
WHERE bi.PARENT_ITEM_ID = 'FG-001' -- 顶层成品物料编码
AND bi.EFF_DATE <= CURRENT_DATE
AND bi.EXP_DATE >= CURRENT_DATE
UNION ALL
-- 递归展开:查询子件的下一级
SELECT
bi.BOM_ID,
bi.PARENT_ITEM_ID,
bi.CHILD_ITEM_ID,
bi.QUANTITY * be.QUANTITY AS QUANTITY,
be.LEVEL + 1,
be.PATH || '->' || CAST(bi.CHILD_ITEM_ID AS VARCHAR(500))
FROM BOM_ITEM bi
INNER JOIN BOM_EXPLOSION be ON bi.PARENT_ITEM_ID = be.CHILD_ITEM_ID
WHERE bi.EFF_DATE <= CURRENT_DATE
AND bi.EXP_DATE >= CURRENT_DATE
)
SELECT * FROM BOM_EXPLOSION ORDER BY PATH;
关键说明:上述递归查询中,
LEVEL 字段标识物料在 BOM 中的层级深度(顶层为 1),PATH 字段记录从顶层到当前物料的完整路径,便于 MRP 计算时进行多层级需求汇总。
4.3 数量关系字段与用量计算
BOM 子表中的 QUANTITY 字段定义了生产一个单位父物料所需消耗的子物料数量。在 MRP 计算中,数量关系是需求展开的核心参数。
| 字段名 | 数据类型 | 说明 | 示例 |
|---|---|---|---|
| QUANTITY | DECIMAL(18,6) | 生产一个单位父物料所需子物料的数量 | 2.000000(表示需要 2 个) |
| SCRAP_PCT | DECIMAL(5,2) | 子物料在生产过程中的损耗百分比 | 5.00(表示 5% 损耗) |
| USAGE_TYPE | VARCHAR(10) | 用量类型:固定用量 / 变动用量 | FIXED / VARIABLE |
MRP 在计算毛需求时,会按照以下公式进行数量展开:
毛需求数量 = 父物料计划数量 × QUANTITY × (1 + SCRAP_PCT / 100)
常见误区:部分系统将 SCRAP_PCT 直接加在 QUANTITY 上,导致 MRP 计算结果偏大。正确的做法是:SCRAP_PCT 作为独立因子参与计算,且仅在父物料层级累加,避免在递归展开时重复计算损耗。
4.4 生效/失效日期与版本控制
BOM 的生效日期(EFF_DATE)和失效日期(EXP_DATE)是 MRP 计算中时间维度的关键约束。通过日期字段,ERP 系统可以支持 BOM 的工程变更(ECO)、版本切换和临时替代。
日期字段的设计原则:
- 生效日期(EFF_DATE):BOM 版本开始使用的日期,MRP 计算时只考虑生效日期 ≤ 计划日期的 BOM。
- 失效日期(EXP_DATE):BOM 版本停止使用的日期,MRP 计算时只考虑失效日期 ≥ 计划日期的 BOM。
- 版本号(VERSION):配合日期字段使用,同一物料可以有多个版本的 BOM,但同一时间只能有一个生效版本。
- 替代 BOM:通过设置不同的生效日期范围,实现临时替代或并行生产。
最佳实践:建议在 BOM_HEADER 和 BOM_ITEM 两个表中都保留 EFF_DATE 和 EXP_DATE 字段。BOM_HEADER 的日期控制整个 BOM 版本的可用性,BOM_ITEM 的日期则支持单个子件的临时替换(如供应商切换、物料淘汰)。MRP 计算时,两个表的日期条件需同时满足。
4.5 BOM 数据模型整体架构
下图展示了 BOM 数据模型中各表之间的关联关系,以及核心字段在 MRP 计算中的流转路径。
4.6 BOM 数据模型设计检查清单
在实施 BOM 数据模型时,建议对照以下清单进行设计评审:
| 检查项 | 说明 | 优先级 |
|---|---|---|
| 父子关系完整性 | PARENT_ITEM_ID 和 CHILD_ITEM_ID 是否都引用了 ITEM_MASTER 表?是否建立了外键约束? | 高 |
| 数量精度 | QUANTITY 字段的数据类型是否支持足够的小数位数(建议 DECIMAL(18,6))? | 高 |
| 日期索引 | EFF_DATE 和 EXP_DATE 字段是否建立了索引?MRP 查询时是否使用了日期过滤? | 高 |
| 递归查询性能 | BOM 层级深度是否有限制?递归查询是否设置了最大递归深度(如 20 层)? | 中 |
| 版本冲突检测 | 同一物料在同一时间点是否存在多个生效的 BOM 版本?是否有唯一性约束? | 高 |
| 替代 BOM 支持 | 是否支持通过日期范围或优先级字段实现 BOM 的临时替代? | 中 |
总结:BOM 数据模型是 MRP 计算的基石。一个健壮的 BOM 表结构设计,需要同时考虑父子关系的递归展开、数量关系的精确计算、时间维度的版本控制,以及数据库层面的查询性能优化。在实际 ERP 实施中,建议在 BOM_ITEM 表上建立 (PARENT_ITEM_ID, EFF_DATE, EXP_DATE) 的联合索引,以加速 MRP 的递归查询效率。