【问题标题】:Many-to-many on single entity with join table具有连接表的单个实体上的多对多
【发布时间】:2018-12-24 19:24:08
【问题描述】:

我有一项任务需要一些“特殊”用户无需登录即可在帐户之间切换。作为起点,我有一个仅包含用户 ID 的连接表。以 PRIMARY_USER_ID 和 SECONDARY_USER_ID 的形式作为来自 USERS 表的外键。首先需要实现的是用户之间所有连接的GET。 [{"primary_username", "primary_email","secondary_username","secondary_email"}]。

我在 User 实体上创建了多对多关系,关系的双方都在 User 上。

@EqualsAndHashCode.Exclude
@ToString.Exclude
@ManyToMany(fetch = FetchType.LAZY, cascade = {
        CascadeType.PERSIST,
        CascadeType.MERGE
})
@JoinTable(name = "CONTACTS_ONE_LOGIN",
        joinColumns = { @JoinColumn(name = "PRIMARY_CONTACT")},
        inverseJoinColumns = {@JoinColumn(name = "SECONDARY_CONTACT")}
)
private Set<Contact> secondaryContacts = new HashSet<>();

@EqualsAndHashCode.Exclude
@ToString.Exclude
@ManyToMany(cascade = {
        CascadeType.REMOVE
},
        mappedBy = "secondaryContacts")
private Set<Contact> primaryContacts = new HashSet<>();

现在的问题是,当我想获取联系人之间的所有连接时,我需要首先从连接表中获取所有信息,然后通过每个 PRIMARY_CONTACT_ID 来获取它的连接联系人。这将导致性能非常低。

我想将其更改为拥有一个 CONNECTED_USERS 实体,它在 USER 上有两个多对一关系,而不是两个 USER ID。

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "PRIMARY_CONTACT_ID")
private Contact contact;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "SECONDARY_CONTACT_ID")
private Contact contact;

我的问题是,这是否会增加性能,因为在我的开发数据库中我没有很多用户来正确测试它?或者有没有更好的方法来做到这一点?

【问题讨论】:

  • 测量并找出答案。

标签: java oracle hibernate


【解决方案1】:

我们更难以猜测您的模型的性能如何,因为我们对您的应用程序、其数据或业务规则一无所知。从您的问题来看,似乎只有少数用户受到此要求的影响。因此,除非您的用户总数达到数十万,否则您可能无需担心。

无论哪种方式,您建议的单独交集表的性能优势都不太可能证明维护它的开销是合理的。我建议您构建一个基于复合函数的索引,类似这样(警告:现在我无法访问数据库,因此以下内容未经测试,可能包含语法错误):

create index connected_users_fbi on your_table (
    case when secondary_contact_id is not null then primary_contact_id end,
     secondary_contact_id);

此索引对于识别主要联系人和次要联系人很有用。它还可能支持通过索引跳过扫描查找连接到辅助联系人(如果您需要该功能)的所有主要联系人。

显然不要相信我的话,而是尝试用真实的数据量对其进行基准测试。您的项目应该有一个性能环境,您可以在其中进行此类测试。如果没有,那么它几乎注定要失败。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-15
    • 2016-11-10
    相关资源
    最近更新 更多