Php 一对多数据库结构优化设计

Php 一对多数据库结构优化设计,php,mysql,database-design,optimization,Php,Mysql,Database Design,Optimization,我正在建立一个库存跟踪系统,供公司内部使用。我正在研究数据库结构,希望得到一些关于哪种设计更好的反馈* 我需要一个递归(我可能用错了这个词…)系统,其中一个部件可以由零个或多个部件组成。我想有两种方法可以做到这一点,但不确定使用哪一种。我不是一个数据库设计专家,所以也许有一个他们的选择,我没有想到 备选案文1: 两个表,一个带有零件id,另一个带有零件id,子零件id(指另一个零件id)和数量。因此,一个表part\u id是唯一的,而另一个表可能有零行或多行,显示构成某个部分的所有部分 备选

我正在建立一个库存跟踪系统,供公司内部使用。我正在研究数据库结构,希望得到一些关于哪种设计更好的反馈*

我需要一个递归(我可能用错了这个词…)系统,其中一个部件可以由零个或多个部件组成。我想有两种方法可以做到这一点,但不确定使用哪一种。我不是一个数据库设计专家,所以也许有一个他们的选择,我没有想到

  • 备选案文1: 两个表,一个带有
    零件id
    ,另一个带有
    零件id
    子零件id
    (指另一个
    零件id
    )和
    数量。因此,一个表
    part\u id
    是唯一的,而另一个表可能有零行或多行,显示构成某个部分的所有部分

  • 备选案文2: 一个带有零件id和部件的表。assembly是一个文本字段,看起来像这样,
    part\u id,quantity;零件编号、数量。。。。然后,我将使用PHP
    explode()
    函数以分号分隔,再以逗号分隔,以获得子部分的数组

我希望这一切都有意义。我正在使用PHP/MySQL


*社区wiki,因为这可能是主观的。

通常,选项1比选项2更可取,尤其是因为部件中的某些零件ID本身就是部件


您必须处理递归或树结构查询。这在SQL的任何方言中都不是特别容易。有些系统对它们的支持比其他系统更好。Oracle有它的CONNECT BY Previor系统(很奇怪,但它有点工作),DB2有递归WITH子句,而且…

当您有数据库引擎处理数据结构时,永远不要使用PHP或C#之类的过程语言来处理数据结构。关系数据结构比存储文本更快、更灵活、更可靠。忘掉选项2吧


您可以使用递归UDF来检索整个树,而无需对此大惊小怪。

在同一个表上使用一个可为空的外键如何?比如:

CREATE TABLE part (
    part_id int not null auto_increment primary key,
    parent_part_id int null,
    constraint fk_parent_part foreign key (parent_part_id) references part (part_id)
)

绝对不是选项2。那是制造麻烦的方法。正确答案取决于可能的组件级别以及您对组件的看法。你认为一个组件(一个由两个或两个以上的原子部分组成的复合对象)本身就是一个部分,它本身可以作为一个子部分使用吗?或者说,组件与原子零件在本质上是不同的吗

如果是前者,则将所有部件和零件放在一个带有PartID的表中,并添加第二个表,该表仅包含由多个其他零件组成的零件的构造细节(这些零件本身可能是更多原子零件的部件)。第二张表如下所示:

   ConstructionDetails
  PartId,  SubPartId, QuantityRequired
如果你认为事情更像第二种方式,那么只把原子部分放在第一个表中,把组件放在第二个表中

   Assemblies
   AssemblyId,  PartId,  QuantityRequired

更好不是“主观的”。这是你必须定义的东西。更好可能意味着“更快”或“更少的SQL”或“更多的SQL”或“使用Oracle的好理由”。你必须更好地定义。仅仅把这个问题变成一个社区维基并不能免除你必须定义对你来说什么是重要的。@s.Lott我故意含糊其辞,不限制我得到的回答。对我来说,更好是更快、更容易维护和最佳实践。我可能并不总是使用最为最好的,但知道什么是共识是好事。”塞缪尔:“最好的”没有一致的意见。你必须定义你的价值和你想要优化的东西。如果有一个预先优化的、一刀切的解决方案,它将已经打包为数据库的标准功能。这些事情涉及权衡,您必须指定在这种情况下您发现什么是重要的。没有通用的“最佳”。@Samuel除了没有“最佳”选项之外,可能已经有数十个(如果不是数百个)与层次结构/树相关的数据库问题了,所以…@s.Lott现在你只是随便说说而已。这实际上是错误的。您是否对此进行了基准测试?SQL层次结构相当复杂。在过程程序中处理的平面表具有更简单的SQL,并且通常比纯SQL版本更快。速度不是数据库的价值主张。解决方案2放弃了真实世界对象的高保真模型。它不会放弃任何速度。你真的不能用一张平桌子做很多事,是吗?这与在文本文件中存储数据是一样的。读取时速度更快,但处理数据要慢得多,也更难。考虑更新、删除、搜索、统计、成本计算等。如果数据是关系型的,那么所有这些都可以通过SQL轻松完成。PHP将永远无法解析大型表。用户定义函数。您可以使用SQL和过程语言定义它们,然后在其他查询、存储过程或其他UDF中调用它们。数据库中用于此数据库的函数。@Alexandar:“你不能用一个平面表做很多事情,是吗?”这就是重点。它更快,但更难使用。对于这样的层次结构,复杂的关系结构很少更快。它们几乎总是更灵活。我建议你删除“更快”这个词。我不同意。它只在一个特定的任务上比较慢——阅读整棵树。因为文本形式充当单个操作的缓存(顺便说一句,如果这种操作太频繁,可以与关系树结合使用),而关系结构提供了所有操作范围,其速度要比处理文本时快得多。