何时在Doctrine2中维持反向关系是否值得?

时间:2011-08-10 00:20:18

标签: doctrine relational-database doctrine-orm one-to-many dql

在Doctrine手册的Constrain relationships as much as possible下,它提供了“消除非必要关联”和“尽可能避免双向关联”的建议。我不明白什么标准会使协会“必不可少”。

我这样说是因为你似乎经常想要从一对多协会的一方而不是从多方面来。例如,我想获取所有用户的活动PhoneNumbers,而不是获取所有活动的PhoneNumbers及其关联的用户。当你必须遍历多个一对多关系时,这变得更加重要,例如:如果您想在过去两天内看到所有使用过MissedCall的用户(MissedCall-> PhoneNumber-> User)。

这就是简单情况下反向关联的样子:

SELECT * FROM User u
LEFT JOIN u.PhoneNumbers p WITH p.active

如果有一种方法可以在DQL中以相​​反的方向跨越给定关系,那将会更加明智,如下面的原始SQL:

SELECT * FROM User u
LEFT JOIN PhoneNumber p ON p.User_id = u.id AND p.active

有人可以解释为什么他们提出这个建议,在什么情况下值得忽略?

- 编辑 -

如果有减轻因素或其他解决方法,请给我简单的示例代码或链接。

当没有定义逆时,我没有看到任何方法来遍历关系的逆,所以我将假设构建自定义DQL 而不是实际上是一个解决方案 - 有一些使用DQL无法实现对SQL的简单连接,并且水合可能无论如何都不会起作用。这就是为什么我不明白为什么添加逆关系是一个坏主意。

2 个答案:

答案 0 :(得分:4)

使用Doctrine,我只在需要时定义关系。这意味着定义的所有关系实际上都在代码库中使用。

对于有大型团队在项目的不同领域工作的项目,并不是每个人都习惯于Doctrine,它是当前的配置,以及急切/懒惰的加载关系。如果您定义双向关系,它们不是必需的,可能没有意义,它可能会导致对以下数据的额外查询:

  1. 可能不会被使用
  2. 可能之前已被选中
  3. 仅定义基本关系将使您能够更好地控制您和您的团队如何遍历数据并减少额外或过大的查询

    Updated 22/08/2011

    基本关系,我指的是你使用的关系。定义一个你不会使用的关系是没有意义的。例如:

    • \Entity\Post\Entity\User\Entity\Comment都有明确的关系
      • 使用$post->user获取作者
      • 使用$post->comments获取所有评论
    • \Entity\User\Entity\Post\Entity\Comment都有明确的关系
      • 使用$user->posts获取所有用户帖子
      • 使用$user->posts获取所有用户评论
    • \Entity\Comment仅与\Entity\User有关系
      • 使用$comment->user获取作者
      • 无法使用$comment->post因为我在我的应用程序中检索不属于的帖子

    我不认为他们是“反向”关系。如果在两个方向上使用数据都有意义,可以将它们视为“双向”。如果它没有意义,或者你不会使用那种方式,那么就不要定义它。

    我希望这是有道理的

答案 1 :(得分:2)

我认为这是一个很好的问题,我很期待别人的回答。

一般来说,我已经将您引用的建议解释为以下经验法则:

如果我不需要访问我的实体内的(反)关联,那么我通常会使它成为单向的。在你的用户和(错过)调用的例子中,我可能会保持它是单向的,并且当我需要获得具有最近未接来电的所有用户的列表时,让一些服务类或存储库处理将奇怪事件的自定义DQL放在一起。这是一个我认为特殊的情况 - 大部分时间,我只对特定用户的调用感兴趣,所以单向关系有效(至少在我有这么多记录之前我认为需要优化)