一个 MySQL 表可以看作是一个队列,每一行为一个元素。每次查询得到满足某个条件的最前面的一行,并将它从表中删除或者改变它的状态,使得下次查询不会得到它。在没有并发访问的情况下,简单地用 SELECT 得到一行,再用UPDATE(或者DELETE)语句修改之,就可以实现。 复制代码 代码如下: SELECT * FROM targets WHERE status="C" LIMIT 1; UPDATE targets SET status="D" WHERE id="id";
复制代码 代码如下: UPDATE targets SET status="D", id=LAST_INSERT_ID(id) WHERE status="C" LIMIT 1; SELECT * FROM targets WHERE ROW_COUNT()>0 and id=LAST_INSERT_ID();
更新:在实现带优先级的队列时这种方法有问题,带有 ORDER BY ... 条件的 UPDATE 语句非常慢,例如:
复制代码 代码如下: UPDATE targets SET status="D" WHERE status="C" ORDER BY schedule ASC LIMIT 1;
而单独查询和更新则是很快的: 复制代码 代码如下: SELECT id FROM targets WHERE status="C" ORDER BY schedule ASC LIMIT 1; UPDATE targets SET status="D" WHERE id="id";
复制代码 代码如下: UPDATE targets, (SELECT id FROM targets WHERE status="C" AND schedule<CURRENT_TIMESTAMP ORDER BY schedule ASC LIMIT 1) tmp SET status="D" WHERE targets.id=LAST_INSERT_ID(tmp.id); SELECT * FROM targets WHERE ROW_COUNT()>0 and id=LAST_INSERT_ID();