2014-11-23 47 views
0

上下文:我試圖設置一個系統,用戶可以請求其他用戶成爲他們的朋友。那些有待處理的朋友請求的用戶可以選擇接受或拒絕所述的朋友請求。MySQL在檢查後插入是否不存在於另一個表中

問題:我想設置一個MySQL查詢,以便當用戶發出好友請求時,查詢將首先檢查發出好友請求的人是否與他們正在交友的人是好友請求,然後再添加請求。

現在我有一個未決請求一張桌子和一臺與朋友與下面的結構:

+---------+----------+   +-------------+-------------+ 
|  friends  |   |  friend_requests  | 
+---------+----------+   +-------------+-------------+ 
| userId | friendId |   | requesterId | confirmerId | 
+---------+----------+   +-------------+-------------+ 
| 11111 | 22222 |   |    |    | 
| 22222 | 11111 |   |    |    | 
| 11111 | 33333 |   |    |    | 
| 33333 | 11111 |   +-------------+-------------+ 
+---------+----------+   

現在讓我們再說一次爲好友用戶11111想嘗試,並要求用戶22222。查詢應該查看好友表,看到他們已經是朋友(即,存在userId = 11111和friendId = 22222的行),因此不會向friend_request表中插入任何內容。如果他們不是朋友,那麼應該在friend_requests中插入一個新行。

我到目前爲止已經試過(和得到一個語法錯誤):

INSERT INTO friend_requests (requesterId, confirmerId) 
    SELECT 11111, 22222 WHERE NOT EXISTS (
     SELECT * FROM friends WHERE userId = 11111 and friendId = 22222 
    ) 

我希望如果可能這樣做的過程中一個查詢。任何幫助編寫這個查詢將不勝感激。

回答

1

不要這樣做!相反,讓數據庫檢查友誼的完整性。換句話說,只是在userIdfriendId對創建一個唯一約束:

create unique index idx_userId_friendId on friends(userId, friendId) 

這會給數據庫的保證作業有沒有重複 - 那麼一個更安全的替代做它在應用層。例如,如果兩個用戶同時交友,你的查詢就有競爭條件。

這並不意味着您需要在添加朋友時檢查錯誤。我建議使用on duplicate key set方法:

賦值實際上什麼都不做,除非在違反唯一約束時防止出現錯誤。

根據您的示例數據,您的「朋友」關係是可交換的。如果是的話,你應該在同一時間做兩刀片:

INSERT INTO friend_requests (requesterId, confirmerId) 
    SELECT 11111, 22222 
    ON DUPLICATE KEY requesterId = VALUES(requesterId); 

編輯:

哎呀,這是兩個不同的表。我認爲這將解決該錯誤以及允許你插入值只有一次:

INSERT INTO friend_requests (requesterId, confirmerId) 
    SELECT requesterId, confirmerId 
    FROM (SELECT 11111 as requesterId, 22222 as confirmerId) rc 
    WHERE NOT EXISTS (SELECT 1 
         FROM friends f 
         WHERE f.userId = rc.requesterId and f.friendId = rc.confirmerId 
        ); 
+0

謝謝你的詳細解答。但是,我已經爲friendId/friendId對的朋友表設置了唯一的密鑰。問題不在於朋友表中會有重複條目,而是用戶可以接收已在其朋友列表中的用戶的朋友請求。目前,一旦好友請求被批准或拒絕,朋友請求就會從表中刪除。所以,我需要在添加新的好友請求之前驗證好友關係不存在。如果我誤解了你的答案,請告訴我。 – brybott 2014-11-23 14:53:30

+0

@brybott。 。 。你是否還要檢查*請求*尚未完成?或者在任一方向允許多個請求?如果是這樣,您可以添加另一個'not exists'子句或在該表上使用唯一索引。 – 2014-11-23 15:05:55

+0

只要friend_request表中沒有相同的requesterId和confirmerId(爲friend_request表設置一個唯一的索引以及處理此問題),就可以允許在任一方向發出多個請求。 – brybott 2014-11-23 15:12:33

0

在SQL Server中我做了這件事

if ((SELECT count(*) FROM friends WHERE userId = 11111 and friendId = 22222)=0) 
    begin 
    INSERT INTO friend_requests (requesterId, confirmerId) 
    end 
相關問題