代码之家  ›  专栏  ›  技术社区  ›  S.C.

数据库设计中的多对多关系

  •  4
  • S.C.  · 技术社区  · 14 年前

    我正在建立一个数据库,它利用了大量的多对多关系。例如,我有部件项和机器项,其中每个部件进入许多机器,每台机器有许多部件。这个数据库的目的是能够输入一个零件列表,并得到一个仅由该列表中的零件组成的机器列表,反之亦然。我是数据库设计新手,所以我目前一直在用翻译表来建模这种关系,比如:

    创建表计算机( 机器名称字符(30) )

    部件号, 部件名称字符(30) )

    部件号, 机器id号

    这似乎是一个非常丑陋和天真的方式去建模这种关系。有没有更好的方法可以做到这一点,比如以某种方式将列表存储和更新到各自表下的单个列中,或者其他一些我还没有想到的更好的方法?我正试图找到一种方法来减少查询时间和后处理强度。

    谢谢。

    6 回复  |  直到 14 年前
        1
  •  3
  •   Jé Queue    14 年前

    这不是幼稚的,这是一个ER模型的正确方法。用关系分离实体,经典的设计模式。不用担心查询/连接开销,RDBMS已经为此进行了优化,并且可以在这些连接查询中运行。

    还可以使关系表具有(part_id,machine_id)作为复合主键。更好的是,将它们创建为 并避免表数据的任何(可忽略的)开销。

        2
  •  8
  •   nizmow    14 年前

    欢迎使用关系数据库。不,没有更好的办法了。我建议给您的表命名稍微好一点:Machine,Part,Machine_Part或类似的东西,因为您可能最终会得到一堆这样的表。

    后处理并不是一个真正的问题,在SQL中使用简单的内部连接或使用ORM处理这些关系相当容易。数据库是用来处理这类事情的。

        3
  •  4
  •   PerformanceDBA    14 年前

    编辑以提高清晰度

    这种结构称为物料清单结构,早在关系模型之前就存在了。当然,我会给你一个关系型的版本。这是一个高性能并且没有处理限制,例如,可以使用递归调用的简单存储过程生成树结构(BoM)报告。

    在我们开始追逐之前需要了解的一些事情。

    1. 你的零件和机器工作台还没有正常化。如果仔细检查它们,会发现许多相同的列(显示了PartId::MachineId、PartName::MachineName)。事实上 除了
      .

    2. 多对多关系(在逻辑上它们是关系,而不是表)在物理层实现为关联表,这是不可能的。你已经有了。你将要看到的可能看起来不同,但事实并非如此。

    从我这里得到的任何信息都是5NF;零重复数据;零更新异常。这在多个生产基地进行生产。碰巧我在我的高级课程中使用了所需的结构作为教程的一部分,所以您可以直接查找它。请随意提出任何与理解或其他方面有关的问题。它出现在教程中,正是因为许多开发人员不了解该结构或如何导航它。请注意非常严格的(经过尝试和测试的)命名约定。

    点击 部分 (您可以忽略模型的其余部分,但我也很乐意回答有关它的问题)。方法论和图表符号都是IDEF1X(它是RM的“严格”格式)。

    Part-Assembly-Component Example

    是的,数据完整性得到了维护, AssemblyComponent搜索从Assembly主键索引(也就是说,它们已经高度优化了,我不需要让它们成为某些供应商,以获得更快的速度)提供100%(允许包含的查询)。第二个唯一索引服务于组件程序集搜索100%。

    享受吧。

        4
  •  3
  •   Aaron Fi    14 年前

    一个清晰的思考方法:逻辑与物理

    两个实体(称为A和B)之间的逻辑多对多关系具有三个表(称为A、B和C)的物理实现。这个实现涉及从a到C的物理一对多关系,从B到C的物理一对多关系。表C称为“连接表”或“连接表”

        5
  •  3
  •   Jay    14 年前

    然而,“机器”可能只是“部件”的一个特例,也就是说,在某种意义上,你认为“一件完整的事情”或一个可交付的项目的部件。

    大多数这样做的人会创建一个层次结构。你有:

    part(part_id, description, ... maybe other data like size and weight, etc ...)
    assembly(parent_part_id, child_part_id)
    

    然后,一个顶级零件可以有多个零部件,而这些零部件中的每一个都可以有其他零部件等。这样做的好处是,当一个组件用于多个最终产品时,您只需描述一次中断。例如,我曾经在一家制造洗碗机的公司工作。在零件表中,我们有一个29B型电动机的记录,该电动机有许多部件——外壳、转子、一些定子、电气线束等,但同一台电动机可能用于几种不同型号的洗碗机。你不想再为每一个洗碗机的马达提供全部零件清单。这不仅是一个痛苦的人键入,但如果你有任何改变,你必须确保改变它无处不在的使用。所以你只需要给马达一次突破,然后把马达作为一个单元引用到所有更高级的组件中。

    是的,有些零件是“最终的”,也就是说,它们不会进行更高级别的装配。但你不需要另一张桌子。这只意味着对于这个特定的部件,在这个子部件所在的位置没有装配记录。

    一些数据库引擎,例如Oracle,有命令来跟踪这样的层次结构。如果你没有,你就得用代码来做。但没那么难。人们总是这样做。

        6
  •  2
  •   OMG Ponies    14 年前

    这是标准化数据—存储 part 记录到 machine 记录。

    我正试图找到一种方法来减少查询时间和后处理强度。