Php,“线程安全”的SQL操作

时间:2014-07-23 18:46:40

标签: php mysql sql thread-safety

让我们谈谈评级系统:用户可以评价其他用户。有一个user表:USER_ID,USER_NAME和rates:RATER_ID,RATED_ID,RATE(字符串) 用户可以对某人进行一次评级,但可以随时改变主意 我知道它有点奇怪,它永远不会发生,但让我们看看它是怎么回事:

check if A ever rated B
if no: INSERT INTO
if yes: UPDATE

所以,在伪代码中:

$rec = SELECT COUNT(*) FROM users WHERE RATER_ID = a AND RATED_ID = b
if ($rec == 0)
{
    INSERT INTO rates (a, b, rateText);
}
else
{
    UPDATE rates SET RATE = rateText WHERE RATER_ID = a AND RATER_ID = b
}

但是出现问题。让我们假设两个费率同时到达(我知道它很奇怪)。

- rate request A: count(*) is 0, so lets insert
- rate request B: count(*) is 0, so lets insert - SQL ERROR!

如何解决它?

2 个答案:

答案 0 :(得分:6)

您需要的通常称为“upsert”操作。也就是说,UPDATE如果它已经存在,则为INSERT

您的RATER_IDRATED_ID列上的

You can set a UNIQUE constraint。这样,一次只能存在一行具有该特定组合。

从那里,使用INSERT... ON DUPLICATE KEYhttp://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html

未经测试,但是像这样:

INSERT INTO rates (a, b, rateText) VALUES (:a, :b, :rateText)
  ON DUPLICATE KEY UPDATE rateText=VALUES(rateText);

答案 1 :(得分:3)

您正在寻找的功能是upsert:如果存在则更新,否则插入。

mysql支持它们:http://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html