2016-11-30 47 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在问题中用“插入新行”的含义。但从我的回答下面的上下文和评论来看,很明显:“两个用户都可以进行多次配对” –