物料清单:一张桌子,或者每个子级别的表格?

问题描述:

我正在与制造业的客户合作,他们的产品是同一批零件的配置。我正在创建一个包含所有有效产品及其物料清单的数据库。在决定物料清单计划实施时,我需要帮助。物料清单:一张桌子,或者每个子级别的表格?

显而易见的解决方案是用接线表许多一对多的关系:

Table 1: Products 
Table 2: Parts 
Junction Table: products, parts, part quantities 

然而,也有我的客户的产品多层次的;

-Assembly 
    -Sub-Assembly 
     -Component 
      -Part 

并允许来自较低级别的项目与任何较高级别项目相关联;

Assembly  |Sub-assembly 
Assembly  |Component 
Assembly  |Part 
Sub-Assembly |Component 
Sub-Assembly |Part 
Component |Part 

我怀疑客户会在未来添加新产品系列时添加更多关卡。

纠正我,如果我错了,但我相信上述关系表将要求越来越多的联结表和查询整数序列(0 + 1 + 1 + 2 + 3 ...)来显示和导出整个比尔可能最终影响性能的材料。

有人建议把一切都在一个表:

Table 1: Assemblies, sub-assemblies, components, parts, etc... 
Junction table: Children and Parents 

这只需要一个连接表中创建许多一对多的关系无限的水平。我不知道我是否相信这个解决方案,但除了意外地将一个项目作为自己的父项并创建一个无限循环并且听起来杂乱无章以外,我无法想到任何其他问题。

我缺乏经验来确定这两种模式中的哪一种或两种都不适合我的客户。我正在MS Access中绘制这些模型,但如果有必要,我愿意将此项目移至更强大的平台。任何输入赞赏。谢谢。

-M

你所描述的是一个层次结构。因此它应采取的形式:

part_hierarchy:

part_id | parent_part_id | other | attributes | of | this | relationship 

所以PART_ID 1可以有一个父PART_ID 10“部件”可以具有parent_part_id 12的(当在该表中查找本身)“大会它会是什么样子:

part_id | parent_part_id 
1  | 10 
10  | 12 

和零件表:

part_id | description 
1  | widget 
10  | widget component 
12  | aircraft carrier 

这是一个LITT简化,因为它没有考虑到你的产品/部件关系,但它将全部使用这种方法进行整合。

不错,简单。现在,无论层级结构如何深入都无关紧要。它仍然只有两列(和任何额外的列需要这种关系的属性,如... create_date,last_changed_by_user,等等。

我会建议比访问更强大的东西,因为它缺乏使用递归CTE(SQL Server,Postgres,Oracle等提供的东西)来选择层次结构的功能。

我会100%避免任何架构,因为层次结构变得更深和更复杂,要求您添加更多的字段或表。那是导致痛苦和遗憾的一条途径。

+0

该模式可在行创造了很多的浪费空间属性补充说,只有对应于一个级别。它也会使验证有问题:何时可以将属性设置为空等。 – nicomp

+0

如果属性仅适用于特定级别,则它不属于该表格。这些将是该部分与其父项之间关系的属性。作为关系一部分的ID的属性可以属于为该层次的分支构建的任何公共表。也许这个层次结构有三个组件。根(部分),分支(纯粹用于像“组件”的关系的ID)和叶子(部分)。或者是反转/颠倒版本,取决于OP的意义。所以4桌。 – JNevill

+0

我认为您的解决方案的组合将为我工作。一个包含所有部件的表格,一个包含部件类型(组件,组件等)的表格,一个部件/部件类型的连接表格以及一个部件/父部件的连接表格。树形结构不会在part/parent part连接表中被推断出来,而不需要指出它是什么样的关系(例如,汇编到子汇编)? – mateohao

由于嵌套级别是任意的,因此可以使用一个表与自引用的parent_id外键。

虽然这在技术上是正确的,但浏览它需要大多数数据库不支持的递归查询。但是,简单有效地访问嵌套部分的方法是将一个“路径”存储到每个组件,这看起来像文件系统中的路径。

举例来说,假设部分ID 1是具有一个子id为2,并且部分ID 2具有ID为3的子部分的顶部电平部分,路径将是:

id parent_id path 
1  null   /1 
2  1   /1/2 
3  2   /1/2/3 

否则这意味着找到的子部分的任何部分的树很简单:

select b.part 
from parts a 
join parts b on b.path like concat(a.path, '%') 
where a.id = ?