【问题标题】:Is composite-primary key the best solution - Hibernate Spring复合主键是最好的解决方案 - Hibernate Spring
【发布时间】:2019-07-10 09:21:44
【问题描述】:

我正在使用 Spring、Hibernate 和 JPA 构建一个聊天应用程序,我想要两个表 - 聊天和消息。聊天会有很多消息,还有 id 和 user_first 和 user_second。现在我正在使用复合主键进行操作,其中复合主键是 user_first 和 user_second,并且 id 是唯一的自动增量:

public class ChatPK implements Serializable {
    protected int firstUser;

    protected int secondUser;
... 

@Entity
@IdClass(ChatPK.class)
@Table(name = "chats1")
public class Chat implements Serializable {
    @Id
    private int firstUser;

    @Id
    private int secondUser;

    @Column(name = "id", unique = true, nullable = false, insertable = false, updatable = false)
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private int id;
...

有没有更好的方法?为什么?

更新:聊天是两个人之间的唯一行,不能与相同的两个用户进行两次聊天。我想将我需要的所有消息与拥有这些消息的两个用户一起获取,因此我可以将发件人 ID 放入 hashmap 键中,并将消息放入一个值中。对于下面的答案,SessionId 与我的桌面聊天所做的事情不同,而不是实现我想要的不同方式。

【问题讨论】:

  • 如果这不是您的实际 id(主键),为什么还要有 id 字段?我要么删除 id 字段,要么将其设为您的 @Id 并在其他两个字段的组合上添加唯一约束。

标签: java spring hibernate composite-primary-key


【解决方案1】:

不,这不是最好的。主键的主要作用是带来唯一性,辅助键是快速访问。密钥也用于缓存,因此密钥的大小也将决定您可以缓存多少。制作复合 ckey 意味着您可能需要覆盖哈希码和等于。你太复杂了。

显然 firstUsier Id 和 second user Id 不足以为您的聊天带来独特性,因为您可以在同一用户之间进行许多聊天会话。

我认为您应该将您的 id 重命名为“sessionID”,将其用作主键,并使您的两个用户之间的两个关系在主键之外。

@Entity
@Table(name = "chats1")
public class Chat implements Serializable {
    @ManyToOne
    private User firstUser;

    @ManyToOne
    private User secondUser;

    @Id
    @Column(name = "sessionId")
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private int sessionId;
...

更新:这个问题变成了复合键的优点和缺点,已在此处详细讨论 Why are composite keys discouraged in hibernate?

【讨论】:

  • 没有聊天意味着它是 2 个人之间的独特聊天,有很多消息,不能与同一个人进行 2 次聊天
  • 我不知道你在构建什么,是学生项目还是真实案例。对真实世界案例的期望是,您将拥有基于用户的聊天唯一性,这一点并不严重。即使您今天这样做,我强烈建议您带上 sessionId,即使您今天不使用它,明天您也可以感谢我:) 如果您坚持使用 OneToOne,只需修改与 OnToOne 的关系
  • 为什么需要会话 ID?我不能使用日期吗?当这个人打开聊天时,它会收到一定数量的消息,然后当用户进一步滚动时,它会占用更多消息,因此不会出现消息过载。
  • 这就是复合键的意思? 2 个人将始终进行独特的聊天。
  • 您也可以使用日期。我个人更喜欢数字键,因为它们更有效。您也可以使用 guid。或者您可以使用日期,只要您的精度足够好 :)
猜你喜欢
  • 2017-07-24
  • 2021-08-29
  • 2014-03-24
  • 1970-01-01
  • 2012-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多