【问题标题】:How to handle many-to-many relationships with more than 2 tables?如何处理超过 2 个表的多对多关系?
【发布时间】:2011-08-25 17:56:38
【问题描述】:

这就是我现在所处的位置。我有四个表:task、project、opportunity 和 task_xref。项目表和机会表都与任务具有一对多的关系。我将这些关系存储在 task_xref 中。每个表的架构看起来像这样(简化):

task
----
id(pk)
name

project
-------
id(pk)
name
...

opportunity
-----------
id(pk)
name
...

task_xref
---------
task_id(task id)
fkey(other table id)

假设项目和商机中的键不同 (GUID),因此商机无法获取项目的任务等等。从表面上看,这很有效,一个外部参照表来维护任务和项目、机会(或将来可能需要任务关系的任何其他表)之间的关系。

我目前的困境是双向的。如果我希望获得单个项目或机会的所有任务,那没问题。如果我要撤回一项任务并想知道相关项目或机会的名称,我不能。我无法知道相关的 fkey 是项目还是机会。将来我可能会有其他具有任务关系的表;虽然我现在有 2 张桌子,但将来可能还会有更多。

到目前为止,我想到了以下可能的解决方案: 1) 为每对单独的外部参照表(例如 task_project_xref、task_opportunity_xref...) 缺点:我必须为每个外部参照表运行查询,以查找任务的关系

2) task_xref 中的第三列指向父表 缺点:这对我来说似乎是一个杂物

3) 以可识别的方式(例如 proj1、proj2、proj3、opp1、opp2、opp3)将主键存储在项目、机会中,这样我就可以通过查看 fkey 来判断任务与哪个表相关 缺点:这感觉就像我正在让项目和机会中的主键变得神奇,赋予它们更多的意义,而不仅仅是作为单个记录的标识符(也许我想多了)

那么我的问题是:还有其他我忽略的解决方案吗?哪个解决方案比其他解决方案更好/更差?

如果可能,我会尽量限制连接,并尽可能提高性能。如果这有助于简化事情,我也不反对在代码中加入数据。

我正在使用 PHP 和 MySQL(目前是 MyISAM 表,但如果有理由会使用 INNODB)。

【问题讨论】:

    标签: mysql many-to-many cross-reference


    【解决方案1】:

    我更喜欢为不同的概念使用单独的外部参照表。这样,一个概念与其任务的关系更易于维护,并且与其他概念与任务的关系隔离开来。

    如果您的设计中的任何表可以有任务,我也许会支持所有相关概念的单个外部参照,然后我只需要一个额外的列指明哪种对象是任务的父对象。

    【讨论】:

    • 在考虑了用户如何与应用程序交互之后,这似乎是一个“正确”的解决方案,至少对于我的特殊情况而言。正如 jodes 指出的那样,无论如何我可能需要 2 个查询。通过这种方式,我坚持让每个概念管理自己的数据的模式。
    【解决方案2】:

    如果 task_xref 有单独的 project_id 和机会_id 字段,您的 SQL 连接会更整洁。这是一个很好的方法,因为查询很简单。此外,通过简单地查看哪些外键不为空,就很容易判断它是什么类型的任务。它也很有效。加入任务时,需要两个查询,因为项目和机会无疑会有不同的结构,所以结果无论如何不能是union'd。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-17
      • 2014-07-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-18
      • 1970-01-01
      相关资源
      最近更新 更多