我有一个用户表,如下所示:
| 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
条目移动到第二个表的建议,但这看起来非常混乱,并且会在所有选择查询中产生开销。
答案 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是受影响的行数,而不是受影响的行数。