2012-08-13 68 views
1

我一直在社交網站上工作。這裏用戶請求另一個用戶成爲他的朋友(朋友請求)。我想到了一個「朋友」表看起來像社交網站的朋友桌

Table Name: Friends 
Coloumns : 
    User1 - Int - FK 
    User2 - Int - FK 
    Request - Enum('0','1') 
    Time - DateTime 

PK - (User1, User2) 

在請求字段「0」時,請求由用戶1發到用戶2,當請求已獲得用戶2「1」被存儲在存儲中。

問題出現在我想要檢索用戶的所有朋友時。我必須每次檢查請求字段是否爲'0'或'1'。還有另一種方法可以做到嗎?如果我有另一張存儲朋友請求的所有細節的表,會更好嗎?

+1

爲什麼這是一個問題?它不應該只要你有請求字段索引。做一個像SELECT * FROM friends WHERE User1 = XX和Request = 1'這樣的查詢應該沒問題。 – 2012-08-13 17:49:51

+0

@MikeBrant如果User1是User2的好友,那麼User2也是User1的好友。因此,查詢將成爲'SELECT * FROM WHERE(User1 = XX或User2 = XX)和Request = 1'。不是很複雜嗎? – Vicky 2012-08-13 18:09:36

回答

1

在評論你基本上指出,建立友誼(而非請求)在您的設置總是對稱。在這種情況下,您基本上有兩種選擇:您可以將其存儲在兩行中,也可以通過匹配任一列來選擇它。前者將產生更簡單的查詢,但後者將確保對稱性是數據庫結構中固有的,並且也將避免存儲重複數據。所以我會選擇後者,即某種形式的WHERE (User1 = XX or User2 = XX)。查詢可能需要兩倍的時間,因爲只有一列的查詢在同一行數上需要,但由於行數僅爲其他存儲方案的一半,因此就性能而言的淨效應應該可以忽略不計。

您是否希望爲請求或已建立的友誼提供單獨的表格取決於這兩者在應用程序中的關聯數據和控制流程方面的相似程度。舉個例子,如果你想給用戶顯示一個單獨的列表,這個列表顯示他已建立的友誼和他的未決請求,可能用不同的顏色或其他,但是在同一個列表中,然後在數據庫中有一個單獨的表格會更多不合適。另一方面,如果你主要分別處理請求和友誼,那麼有兩張表會更自然。如果在某個時候,你認爲一個freindship需要像share_calendar這樣的屬性,而一個請求需要像confirmation_key這樣的屬性,或者其他什麼,那麼你會更好地使用不同的表格。

如果您決定將此表製作爲單個表格,我會爲該枚舉提供更多描述性值,例如調用列status和值requestedestablished。舉個例子,我乍一看將request = 1的一個值解釋爲「這只是一個請求,而不是一個確定的freindship」,與你所關聯的含義完全相反。當不同的人需要維護代碼時,這種歧義可能導致錯誤。在幾年之內,你將足夠與現在不同,你甚至可能會誤解你的舊代碼。所以要在那裏描述。

還有一點需要注意:您可能總是使用視圖來調整數據庫對查詢的顯示方式。例如,你可以創建一個視圖

CREATE VIEW SymmetricEstablishedFriends AS 
SELECT User1 AS Me, User2 AS Friend, Time 
FROM Friends 
WHERE Status = 'established' 
UNION 
SELECT User2 AS Me, User1 AS Friend, Time 
FROM Friends 
WHERE Status = 'established' 

這將限制數據只建立友誼,並將照顧對稱的東西給你。在查詢中使用這些視圖,可以避免在每個查詢中處理表結構的所有細節。如果你改變這些細節,將會有更少的地方需要改變。

+0

Thanx。我想我得到了我的答案。 – Vicky 2012-08-13 20:39:53

1

我會打破你的數據requestsfriendships。當request被批准時,將其轉換爲friendship。他們確實是兩個不同的對象,應該這樣對待。

Requests :: 
    requesting_user_id : int() 
    requested_user_id : int() 
    date_requested  : datetime() 
    status_id   : int() 

Statuses :: 
    (Active, Declined, Accepted, Ignored) 

Friendships :: 
    friendship_id  : int() 
    user_id   : int() 
    friend_id   : int() 

也許刪除請求,如果它被拒絕,或有一個列(讓人們不要重複請求同一用戶的友誼)。你不得不請求轉換成兩個友誼(每個方向一個),便於索引

SELECT friend_id FROM friendships WHERE user_id = ? 
+0

所以我應該存儲兩個元組,像user1,user2和user2,user1。這樣對嗎? – Vicky 2012-08-13 18:12:30

+0

在'友誼'?是的,這似乎是有道理的。 – 2012-08-13 18:27:08

+0

插入2行並刪除2行看起來像是一個漫長的過程。 – Vicky 2012-08-13 19:15:51