2014-03-30 74 views
1

我正在構建一個數據庫以保存我的應用程序用戶之間的友誼。
我用來與MySQL實例進行通信的服務器是使用Node.js(Express)編寫的。如果select爲空,則插入MySQL以避免雙向重複

我的表'友誼'主要包括兩個INT,它們對應於(外鍵)到用戶ID。 我想避免重複的雙向(1,2與2,1),所以我需要編寫一個查詢,其執行以下操作:

INSERT INTO friendships f (id_1, id_2) VALUES (?, ?) IF (SELECT * FROM friendships s WHERE s.id_1=? AND s.id_2=?) IS NULL ; 

顯然,這並沒有真正的工作。當然,我會讓最後兩個問號與第一個問號相比有相反的值,並且在id(id_1,id_2)上有一個UNIQUE鍵。

這些問題的通常答案是「只需按大小排列您的ID以避免重複」,這是一個很好的答案。但在我的情況下,我想記錄誰發送了朋友請求(以及誰批准),而不使用任何額外的變量(和額外的查詢)。

此外,我不想爲此使用代碼,以避免「併發」問題。

謝謝!

回答

2

在MySQL中,您可以使用執行檢查的觸發器來執行此操作。一些其他數據庫具有功能索引,計算列上的索引或檢查約束來幫助實現此功能。

如果你想要做的insert檢查,你可以這樣做:

INSERT INTO friendships(id_1, id_2) 
    select new1, new2 
    from (select ? as new1, ? as new2) t 
    where not exists (select 1 
         from friendships f 
         where f.id_1 = new2 and f.id_2 = new1 
        ); 

你也應該有id_1和​​唯一索引:

create unique index idx_friendsships_id1_id2 on (id_1, id_2); 

編輯:

基本查詢是:

INSERT INTO friendships(id_1, id_2) 
    select ?, ? 
    from dual 
    where not exists (select 1 
         from friendships f 
         where f.id_1 = ? and f.id_2 = ? 
        ); 

但是你必須以正確的順序得到參數,所以早期的方法不太容易出錯。

+0

是的,它的工作原理!:) 是不是可以做少選擇?這種查詢不會花費更長的時間嗎? 是唯一索引是必要的,我編輯的問題提醒說.. 哦,並修復你的答案接近尾聲,替換「和new1」與「= new1」 –

+0

@guy_m。 。 。我不擔心單行更新的性能。這只是做一個'不存在'的索引查找。多出一層'select'的原因是你只能傳入一次參數。 –

+0

是隻傳遞一次參數很酷:)你能告訴我怎麼做,如果通過它們兩次是好的我?有時候我更喜歡簡單的查詢,而不是複雜的查詢。謝謝 –