簡體   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