有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Hibernate:复合PK与代理PK中的观点

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

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

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

他们继续说,当使用代理键时,在进行连接时会使事情复杂化,并且当使用代理键时,有几种情况是不可能执行某些操作。虽然我很抱歉我不能在这里解释细节,因为他们解释的时候我不够清楚。也许下次我会说更多的细节

我目前正在尝试做一个项目,并希望尝试代理键,因为它不会在表之间重复,我们可以更改业务列值。当需要某种业务价值组合的唯一性时,我可以使用以下方法:

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

但是我仍然有疑问,因为前面讨论过复合密钥

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


共 (2) 个答案

  1. # 1 楼答案

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

    如果某个值包含以下特征,则该值是PK的最佳候选值:

    1. 它是不变的。它永远不会改变
    2. 独一无二。两个记录永远不会共享同一个ID

    也就是说,在现实世界中,几乎不可能永远拥有具有这些特征的任何东西。我的意思是,即使今天有些东西是不变的和独特的,但这并不意味着它永远都是这样

    所以,尽可能使用代理密钥。仅对遗留数据库使用自然密钥。远离那些认为自然键比代理键更好的朋友(开玩笑):-)

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

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

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

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

  2. # 2 楼答案

    Hibernate似乎鼓励使用代理键。我更喜欢使用复合键,但不想与框架对抗,在Hibernate中使用复合键会变得很麻烦。因此,为了充分利用这两个世界,我使用了一个代理键,但也用@naturaid标记了我的潜在复合键列,以便Hibernate为我创建唯一的约束。@NaturalId的默认可变性为false,因此如果需要更新“复合键”字段,请使用@NaturalId(可变性=true)