【问题标题】:Hibernate : Opinions in Composite PK vs Surrogate PKHibernate:复合 PK 与代理 PK 中的意见
【发布时间】:2011-06-02 10:35:53
【问题描述】:

据我了解,每当我在 JPA/Hibernate 实体内的 Long 字段上使用 @Id 和 @GeneratedValue 时,我实际上是在使用代理键,我认为这是定义主键的一种非常好的方法我在使用复合主键方面不太好的经验,其中:

  1. 有超过 1 个业务价值列组合成为唯一的 PK
  2. 复合 pk 值在表详细信息中重复
  3. 无法更改复合 PK 中的业务价值

我知道 hibernate 可以支持这两种类型的 PK,但是我之前与有经验的同事的聊天让我感到疑惑,他们说复合 PK 在执行复杂的 SQL 查询和存储过程过程时更容易处理。

他们继续说,当使用代理键时,在加入时会使事情复杂化,并且在使用代理键时不可能做一些事情的情况有多种。虽然我很抱歉我不能在这里解释细节,因为他们解释的时候我不够清楚。也许下次我会提供更多细节。

我目前正在尝试做一个项目,并想尝试代理键,因为它不会跨表重复,我们可以更改业务列的值。而当需要一些商业价值组合的独特性时,我可以使用类似的东西:

@Table(name="MY_TABLE", uniqueConstraints={
    @UniqueConstraint(columnNames={"FIRST_NAME", "LAST_NAME"}) // name + lastName combination must be unique

但由于之前关于复合键的讨论,我仍然存在疑问。

你能分享你在这件事上的经验吗?谢谢!

【问题讨论】:

    标签: java database hibernate database-design


    【解决方案1】:

    关于任何应用程序的第一条规则是需求会发生变化。时期。所以,今天看起来很适合 PK 的东西明天可能根本就不是 PK。

    如果一个值包含以下特征,则它是一个很好的 PK 候选者:

    1. 它是不可变的。它永远不会改变。
    2. 独特性。两条记录永远不会共享同一个 ID。

    也就是说,在现实世界中以永久的方式拥有具有这些特征的任何东西几乎是不可能的。我的意思是,即使某些东西在今天是不可变的和独特的,但这并不意味着它会一直如此。

    因此,尽可能使用代理键。仅对遗留数据库使用自然键。并且远离那些建议自然键比代理更好的朋友(开玩笑):-)

    当然:您可以使用数据库中的约束来强制执行唯一性规则(就像您在示例中所做的那样),如果这是业务规则,则两条记录不可能共享相同的值。当未来业务逻辑发生变化时,您会很高兴看到您使用了代理键 ;-)

    但不要相信 stackoverflow 上的随机家伙。阅读维基百科的这两篇文章:

    http://en.wikipedia.org/wiki/Surrogate_key

    http://en.wikipedia.org/wiki/Natural_key

    【讨论】:

      【解决方案2】:

      Hibernate 似乎鼓励使用代理键。我更喜欢使用复合键,但不想与框架抗争,而且在 Hibernate 中使用复合键会很麻烦。因此,为了两全其美,我使用代理键,但也使用@NaturalId 标记我可能的复合键列,以便 Hibernate 为我创建唯一约束。 @NaturalId 的默认可变性为 false,因此如果您需要更新“复合键”字段,请使用 @NaturalId(mutability=true)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-17
        • 1970-01-01
        • 1970-01-01
        • 2011-02-13
        • 1970-01-01
        相关资源
        最近更新 更多