请选择 进入手机版 | 继续访问电脑版

faith287

金牌服务用户

17

主题

43

帖子

320

积分

金牌服务用户

积分
320
faith287
金牌服务用户   /  发表于:2025-12-29 09:38  /   查看:99  /  回复:4
30金币
现在一个生产订单,订单里面有产品的BOM,BOM里面还有半成品,半成品还有相应的BOM,依次类推,如何直到生成没有bom为止呢

最佳答案

查看完整内容

大佬您好,从咱们这个描述中,这种结构本质上是一个 有向无环图(DAG),而不是简单的树形结构,主要是同一个子BOM可以被多个父级半成品引用。 这个的数据存储,也可以在关系型数据库中存储,但是存储的方式,不再是id和pid的方式,而是需要两张表组合,查询也需要递归的方式。 1、物料信息表,记录所以的物料信息,没有物料之间的关系,比如下面的数据表 创建SQL如下: 2、物料信息关系图,这个表中,无论是子BOM ...

4 个回复

最佳答案
最佳答案
Grayson.Shang活字格认证 Wyn认证
超级版主   /  发表于:2025-12-29 09:38:54
来自 5#
ddb505 发表于 2025-12-29 15:26
请教大佬,如果用第2种方式,如果有相同的子级BOM该如何引用到另一个BOM中?在数据存储中如何设计?

大佬您好,从咱们这个描述中,这种结构本质上是一个 有向无环图(DAG),而不是简单的树形结构,主要是同一个子BOM可以被多个父级半成品引用。

这个的数据存储,也可以在关系型数据库中存储,但是存储的方式,不再是id和pid的方式,而是需要两张表组合,查询也需要递归的方式。

1、物料信息表,记录所以的物料信息,没有物料之间的关系,比如下面的数据表

创建SQL如下:
  1. CREATE TABLE materials (
  2.     material_id   VARCHAR(50) PRIMARY KEY,  -- 物料编码
  3.     name          VARCHAR(255) NOT NULL,
  4.     type          ENUM('raw', 'semi', 'finished') NOT NULL, -- 原材料/半成品/成品
  5.     unit          VARCHAR(20),
  6.     version       VARCHAR(20) DEFAULT '1.0'  -- 支持版本控制(可选)
  7. );
复制代码


2、物料信息关系图,这个表中,无论是子BOM,还是父BOM,都可以被多次引用

创建SQL如下:
  1. CREATE TABLE bom_items (
  2.     id            BIGINT AUTO_INCREMENT PRIMARY KEY,
  3.     parent_id     VARCHAR(50) NOT NULL,      -- 父物料ID(半成品或成品)
  4.     child_id      VARCHAR(50) NOT NULL,      -- 子物料ID(可以是原材料或另一个半成品)
  5.     quantity      DECIMAL(18,6) NOT NULL DEFAULT 1.0,
  6.     unit          VARCHAR(20),
  7.     effective_date DATE,                    -- 生效日期(用于版本/时间维度)
  8.     obsolete_date  DATE,                    -- 失效日期(可选)

  9.     FOREIGN KEY (parent_id) REFERENCES materials(material_id),
  10.     FOREIGN KEY (child_id)  REFERENCES materials(material_id),

  11.     UNIQUE KEY uk_parent_child_active (parent_id, child_id, effective_date)
  12. );
复制代码


最终的查询需要递归的方式,测试SQL如下:

  1. WITH RECURSIVE bom_tree AS (
  2.     -- 锚点:从顶层成品开始
  3.     SELECT
  4.         parent_id,
  5.         child_id,
  6.         quantity,
  7.         1 AS level
  8.     FROM bom_items
  9.     WHERE parent_id = '1'  -- 指定成品编码

  10.     UNION ALL

  11.     -- 递归:展开子项(如果子项本身也是半成品)
  12.     SELECT
  13.         bi.parent_id,
  14.         bi.child_id,
  15.         bi.quantity * bt.quantity AS quantity,  -- 累计用量(可选)
  16.         bt.level + 1
  17.     FROM bom_items bi
  18.     INNER JOIN bom_tree bt ON bi.parent_id = bt.child_id
  19. )
  20. SELECT * FROM bom_tree;
复制代码


测试结果如下:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 使用道具 举报
豪~豪悬赏达人认证 活字格认证
银牌会员   /  发表于:2025-12-29 09:41:11
2#
可以问问AI让AI给一个存储过程
回复 使用道具 举报
Grayson.Shang活字格认证 Wyn认证
超级版主   /  发表于:2025-12-29 10:02:09
3#
大佬您好,一般咱们提到的这种数据,存储方式有两种
1、用于临时生成,或者临时使用,数据可能不会存储到关系型数据库中,主要是在代码或者非关系型数据库中,就是树形的数据存储。
最外层的BOM是,一个数组,子级放在每一个BOM对象的属性下,若是还有,则继续存储。
这个方式的缺点就是,关系型数据库没有对应的数据类型,只能以文本的形式存储,需要做反序列化,使用起来比较麻烦

2、在咱们日常数据存储中,不确定层级的,一般就是ID与父ID的存储,现在使用比较多的就是这种方案。
回复 使用道具 举报
ddb505
中级会员   /  发表于:2025-12-29 15:26:54
4#
Grayson.Shang 发表于 2025-12-29 10:02
大佬您好,一般咱们提到的这种数据,存储方式有两种
1、用于临时生成,或者临时使用,数据可能不会存储到 ...

请教大佬,如果用第2种方式,如果有相同的子级BOM该如何引用到另一个BOM中?在数据存储中如何设计?
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 立即注册
返回顶部