【问题标题】:Composite primary keys or surrogate primary key on relationship entities (entities that are also relations) in Doctrine2Doctrine2 中关系实体(也是关系的实体)上的复合主键或代理主键
【发布时间】:2013-05-17 09:56:16
【问题描述】:

我有一个大型数据库,其中有关系实体。这正是因为 Doctrine 2 手册中的the following comment:我需要在我们的关系中存储额外的属性,因此关系变成了一个实体。

通常我们为实体使用生成的 id,为关系使用复合键。在这种情况下,实体是一种关系,因此选择有点复杂......

请注意,我在这里不是在谈论自然键。我正在使用一个复合键,它由 id 组成,这些 id 是在各自拥有的实体中使用自动增量策略创建的整数。

我发现在关系实体上使用复合主键的一些缺点

  • 我需要在创建实体及其关系之间调用persist(以在实体上生成键,然后才能将其用作复合主键中的外键)。
  • 要将其他实体与关系实体相关联,我们需要在这些实体中再次为复合键中使用的 id 添加列。如果我要使用代理主键,我只需要一列来保存那个 id。

我还看到了使用复合键的一些优点,例如:

  • 它们消除了对某些连接查询的需要,相反,您可以构建查询以使用复合键直接提取信息。

但目前使用复合键的最重要的论点如下:

  • 当 User 和 SomeEntity 之间的关系被删除并随后再次创建时(这种情况很可能发生在我们的应用程序模型中),我们也需要恢复对所有其他相关实体的访问。 如果 User 和 SomeEntity 之间的关系是使用代理主键上的自动增量策略创建的。恢复的(新)关系将获得一个新的主键(id)。因此,相关实体(使用“旧”键存储)不再可访问。 如果我在关系上使用复合键,我可以简单地恢复关系(它获得相同的复合键值)并且我可以立即再次访问其他相关实体。

有没有遇到过类似情况的人?是否有其他解决方案可以使其正常工作。有没有我遗漏的重要缺点或优点(使用 Doctrine ORM 时)。

我能想到的另一种选择是向 User SomeEntity 关系添加一个状态。我们可以将状态更改为禁用、启用,而不是删除条目。这样我们就可以使用代理键而不是复合键,因为条目永远不会被删除...

非常感谢您的反馈...

对于感兴趣的人,这里还有关于 Stack Overflow 上代理键与复合键的精彩讨论:(click)

【问题讨论】:

    标签: doctrine-orm foreign-keys relationship composite-primary-key surrogate-key


    【解决方案1】:

    我建议让你的两个外键成为复合主键。

    您的关联实体将通过其两个关系的 id 来标识。

    理论上,Doctrine 的 UnitOfWork/CommitOrderCalculator 应该能够以正确的顺序插入元素,因此,您不必处理持久顺序。

    您的映射最后会如下所示(注释示例):

    <?php
    
    class UserGroup
    {
        /**
          * @ORM\ManyToOne(targetEntity="User")
          * @ORM\Id
         **/
        public $user;
    
        /**
          * @ORM\ManyToOne(targetEntity="Group")
          * @ORM\Id
         **/
        public $group;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-11
      • 1970-01-01
      • 2014-10-26
      • 2013-02-13
      相关资源
      最近更新 更多