2016-11-30 90 views
6

我有一個表「匹配」就像更新的行是否存在以其他方式插入

id|user1|user2|paired 
--+-----+-----+--------+ 
1 |U_1 |null |false 

我需要一個新的用戶「U_2」匹配到配對=虛假記錄,或創建表的新條目如果沒有找到未配對的行。

這個數據庫連接到多個用戶可能試圖配對的服務器,所以我需要找到最好的解決方案,使其更快,因此它不會長時間鎖定表。

我想出了一個解決辦法是

int matchId = select id from match where ((user1 != 'U_2') AND (paired = false)); 

if(matchId > 0) 
then 
    update table match set user2 = 'U_2' where id = matchId; 
else 
    insert new row. 

請提出一個更好的辦法。

在此先感謝。

+0

您現有的解決方案對我來說看起來很好。這看起來很簡單,你看到一個特定的性能問題嗎? – worpet

+1

感謝您的回覆。我想知道是否有連擊方式來做到這一點。當查詢一個非常大的表時,查詢數據庫2次可能會增加響應時間。並且還有可能有2個或更多用戶從第一個查詢獲得相同的ID。然後他們最終可能會更新同一行。 –

回答

8

可以

  • 添加獨特的指數user1和user2來提高速度和保證完整性。
  • 使用事務來避免衝突。
  • 在一個更新組合選擇和更新查詢:

    update table match 
    set user2 = 'U_2' 
    where ((user1 != 'U_2') AND (paired = false)) 
    LIMIT 1; 
    
  • 檢查更新是否affected rows。如果不是,插入新行。

如果我正確地理解你的內涵,你還可以:

  • 刪除該列paired,這似乎是多餘的,因爲它始終是falseuser2=null
+0

但這兩個用戶可以配對多次。也是這樣,我將無法將數據從更新的行發送給用戶請求匹配......或者有沒有辦法呢? –

+0

我同意code_angel的回答。如果沒有受影響的行,使用更新並插入。如果更新成功,只需使用select獲取信息(使用時間戳來獲取該用戶的最新記錄)或者檢查[this](http://stackoverflow.com/questions/1388025/how-to-get-id-最後更新行中的mysql)線程直接從更新中獲取id。 –

+0

如果應該允許多個匹配,則按照S. Roose所述,使用額外的時間戳列進行匹配。您可以通過user1,user2和時間戳創建唯一鍵。或者剛剛超過user1和時間戳。這取決於細節。 –

3

單聲明做一個或另一個:

INSERT INTO match 
    (user1, paired, user2) 
    VALUES 
    ('U_2', false, 'U_2') -- either insert this 
ON DUPLICATE KEY UPDATE 
    user2 = VALUES(user2); -- or update this 

加上

PRIMARY KEY(user1, paired) -- a UNIQUE key to control what is "DUPLICATE" 
+0

不適用於這種情況。有一個多對多的關係。它沒有完全定義OP在問題中用「插入新行」的含義。但從我的回答下面的上下文和評論來看,很明顯:「兩個用戶都可以進行多次配對」 –