簡體   English   中英

同桌上的多對多

[英]Many-to-many on same table

有趣的是,我從未遇到過這個!

我從來沒有想到一個人可以在一張桌子上擁有“多對多”的關系 - 直到我開始研究用戶可以互相“交朋友”的系統(社交網絡)。

標准查找表,至少在我習慣使用它的方式,在這里是不合適的。 讓我們保持簡單:

用戶表具有“id”和“name”列。

User_relationship表具有“uid1”和“uid2”,表示“朋友”或“芽”或“好友”或“其他任何”的用戶。

很明顯這里的問題是什么 - uid1和uid2是來自同一個表的同一列的相同數據類型,這意味着唯一鍵變得有缺陷。

例如:uid1 = 1 uid2 = 2

是相同的:

uid1 = 2 uid2 = 1

因此,如果查詢執行錯誤,則可以返回2條記錄或0條記錄。

本着設計好表的精神,我不想兩次掃描整個表以檢查現有值。

處理這個有什么技巧嗎? 這是一個從未發生過的設計問題,它讓我感到煩惱,因為我知道有一些簡單的技巧可以讓它發揮作用。

在你提問之前,我還沒有嘗試過任何東西,因為我已經看到我最喜歡的關聯方式(查找表)不足以滿足我的需求,我需要一些幫助 - 我在SO或Google上找不到任何東西:(

提前致謝。

如果您描述的關系是對稱的,如“Bob是Joe的朋友”意味着“Joe也是Bob的朋友”,那么您可以在代碼中確保2個用戶ID中的較小者繼續第一列,較大的一列在第二列。 這種約束幾乎可以確保查找表中的記錄是唯一的。 這也意味着當您執行查找時,通常必須搜索兩列。

例如,如果您試圖獲取Bob的所有朋友,則必須在任一列中查詢具有Bob ID的記錄。 這會導致更多代碼,並可能對性能產生影響。

如果關系可以是不對稱的,如“Bob是Joe的朋友”並不一定意味着“Joe也是Bob的朋友”,那么每對用戶需要2個條目:Bob - Joe和Joe - Bob。 這意味着您的查找表將包含兩倍的條目,並且您的站點對跟蹤器非常友好:D當然,即使您的關系是對稱的,您仍然可以選擇應用此系統。

使用此方法,如果您想獲得Bob的所有朋友,您只需在第一列中選​​擇具有Bob ID的記錄。 這可能意味着更快的查找速度和更少的代碼供您編寫,但同樣,這意味着您在數據庫中占用更多空間。

意味着唯一鍵變得有缺陷。

 uid1 = 1 uid2 = 2 

是相同的:

 uid1 = 2 uid2 = 1 

不,不是。

例如,在Facebook上,我有一些客戶發出請求成為我從未接受的“朋友”......因為他們只是熟人。

同樣,我可能會將一些人標記為最好的朋友,他們沒有回應,反之亦然。 或許我忽略了一些而他們不是。

基本上, (uid1, uid2)元組中的信息比僅僅ID更多。

確保在決定在表上添加例如uid1 < uid2約束之前,您永遠不需要處理這些情況。

這並不罕見。

通常所做的是存在一個表,就像在大多數關系中一樣,它由兩個列組成,每個列是構成主鍵的兩個表的id。

正如您所說的userId1和userId2。 如有必要,可以將屬性添加到關系中(例如友誼分類)。

當用戶1與用戶2成為朋友時,通常有兩個插入,(1,2)和(2,1)。

與defriending相同的事情,需要有兩個刪除。

您最終可能會將自己視為朋友,這可能對系統的實際運行至關重要。 如果用戶只能查看他朋友的照片,那么如果他不是自己的朋友,某些系統可能不允許他看到他自己的照片。

它非常依賴於如何在數據庫之上編寫應用程序。

我同意其他人所說的,對於一個關系(1:2和2:1)有2個插入並不是一個壞主意。 這實際上有助於擴展現代社交網絡中常見的一些功能。 我能想到的一些實際使用案例是關系或其他屬性的描述。 雖然個人仍然是朋友,但他們保持着彼此不同的環境。 在1:2關系中,Bob正在關注Joe的更新並將他列在最好的朋友列表中(添加bff列),而在2:1中Joe沒有Bob在bff列表中並且不關心他的帖子(在列之后) 。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM