Hibernate:复合PK与Surrogate PK的观点

ber*_*tie 5 java database database-design hibernate

据我所知,每当我在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
Run Code Online (Sandbox Code Playgroud)

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

你能分享一下这方面的经验吗?谢谢 !

jpk*_*ing 11

关于任何应用程序的第一条规则是需求发生变化.期.因此,今天看起来像PK的好候选人可能不会是明天的PK.

如果值包含以下特征,则值是PK的良好候选:

  1. 这是不可改变的.它永远不会改变.
  2. 唯一性.两条记录永远不会共享相同的ID.

也就是说,在现实世界中以永恒的方式拥有这些特征几乎是不可能的.我的意思是,即使今天某些东西是不可变的和独特的,但这并不意味着它总是那样.

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

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

但是不要相信stackoverflow上的随机花花公子.阅读维基百科的这两篇文章:

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

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