mysql - 通过同时请求防止重复的“活动”条目

时间:2014-02-21 20:46:04

标签: php mysql

我有一个用户表,如下所示:

| id | username | active |

可能有多个条目具有相同的用户名和active=0,但只有一个具有相同用户名的唯一条目已设置active=1

确保两个同时请求不能创建重复项的最佳方法是什么? (Session1:SELECT;0 rows, Session2:Select;0 rows, Session1:Insert, Session2:Insert =>重复条目)

我发现我可以设置active=NULL而不是active=0并将用户名和活动设置为唯一,这样可以达到我想要的效果 - 但这似乎是一个相当hacky解决方案并且没有在所有数据库引擎中都能可靠地工作。

我已经看到了将active=0条目移动到第二个表的建议,但这看起来非常混乱,并且会在所有选择查询中产生开销。

3 个答案:

答案 0 :(得分:1)

您可以使用表格锁定。该命令锁定表并阻止每个人写入它。

<?
    $dbh->exec("LOCK TABLES tbl WRITE");

    // Check whether you have an active element.
    // You can make it inactive or whatever. You
    // are the only one who has access to this table.

    $dbh->exec("UNLOCK TABLES");
?>

您可以在documentation

中详细了解相关信息

答案 1 :(得分:0)

将这些信息分开并不是很混乱。如果你现在一个记录的活动设置为true,你真的不需要写其他条目将它设置为0:规则说明如此。这意味着你要重复信息,这比有两个表(IMO非常好)更糟糕。

这意味着您认为您的数据库不在second normal form

基本上:你说的是“第3行是活动行,第4行不是,第5行不是,第6行不是”......等等。 “第3行是活动行”就足够了

答案 2 :(得分:0)

如果您想坚持使用您的设置,请使所有INSERT使用active = 0。然后你可以运行UPDATE来设置active = 1,LIMIT为1.这很麻烦,但是应该可以工作。

UPDATE table SET active=1 WHERE username="<name>" ORDER BY active DESC LIMIT 1

ORDER BY将确保active = 1记录浮动到顶部,LIMIT将确保仅为更新“选择”1条记录。 UPDATE LIMIT是受影响的行数,而不是受影响的行数。