繁体   English   中英

具有连接表的单个实体上的多对多

[英]Many-to-many on single entity with join table

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

我在用户实体上创建了多对多关系,关系的两端都在用户上。

@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;

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

由于我们对您的应用程序,其数据或业务规则一无所知,因此我们很难猜测您的模型的性能如何。 从您的问题来看,似乎只有少数用户受到此要求的影响。 因此,除非您的总用户人数成千上万,否则您不必担心。

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

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

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

显然,我不相信我的话,而是尝试使用实际数据量对其进行基准测试。 您的项目应该有一个可以进行此类测试的性能环境。 如果不是这样,那就注定了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM