Php 在cron作业中迭代活动使用的数据库表,而不丢失任何行
在执行长操作的多个过程时,如何正确地迭代数据库查询的所有行而不丢失任何行?在我的例子中,我有字母数字id,所以id列不可靠 主要问题是,查询结果可能会在每个cron任务执行之间发生变化 第一个想法可能是存储偏移量/“处理的行数”。但是,如果已经处理的行中有一行被删除,其他行将移动,第一行将被跳过 如果我存储最后一个处理的行的id并跳到它后面的那一行,我有一个更糟糕的问题:如果删除了那一行,下一个cron作业将跳过剩下的每一行 有没有其他像这样迭代表的“标准”方法Php 在cron作业中迭代活动使用的数据库表,而不丢失任何行,php,algorithm,orm,cron,iteration,Php,Algorithm,Orm,Cron,Iteration,在执行长操作的多个过程时,如何正确地迭代数据库查询的所有行而不丢失任何行?在我的例子中,我有字母数字id,所以id列不可靠 主要问题是,查询结果可能会在每个cron任务执行之间发生变化 第一个想法可能是存储偏移量/“处理的行数”。但是,如果已经处理的行中有一行被删除,其他行将移动,第一行将被跳过 如果我存储最后一个处理的行的id并跳到它后面的那一行,我有一个更糟糕的问题:如果删除了那一行,下一个cron作业将跳过剩下的每一行 有没有其他像这样迭代表的“标准”方法 我在php中使用第三方orm引擎
我在php中使用第三方orm引擎,使用sql作为数据存储,但我认为这是一个更一般的问题,因此任何人都可以更适当地重新标记它。大多数DBMS都有可靠的标准排序。因此,最简单的解决方案是不使用任何排序并使用限制和偏移定义。例如,对于MySQL,您可以这样做:
SELECT *
FROM mytable
LIMIT 10,10
;
这应该是可靠的
如果您想考虑删除的行,我将使用某种队列。例如:
CREATE TABLE item(
id INT PRIMARY KEY
);
CREATE TABLE job (
id INT PRIMARY KEY
);
CREATE TABLE job_queue(
id INT PRIMARY KEY,
job_id INT,
item INT,
FOREIGN KEY job_id REFERENCES job(id),
FOREIGN KEY item REFERENCES item(id)
);
然后,您可以通过运行以下命令将所有项目添加到队列:
INSERT INTO job_queue (job_id, item_id)
SELECT 1, id
FROM item;
现在,您可以通过运行查询可靠地获取项目:
SELECT *
FROM job_queue
WHERE job_id = 1
LIMIT 10;
DELETE FROM job_queue WHERE id IN (
SELECT id
FROM job_queue
WHERE job_id = 1
)
但有许多可能的有效解决方案。最终答案在很大程度上取决于您的需求。如果任意两个cron同时命中,您可以使用DB事务来解决并发问题。要知道下一行从哪一行开始,可以在DB say
processed
中有一个额外的列,它存储一些整数,比如1。因此,下一次cron命中将获取processed
列中没有1的行 我想,我不确定是否在没有订单的情况下使用LIMIT,这要视情况而定。某些DBMS有一个内部行id,用于缺少顺序的情况。据我所知,以下DBMS是关于这方面的:MySQL、PostgreSQL、MSSQL如果您按ID asc(例如)排序选择并存储最后处理的ID。下次只需使用WHERE ID>stored,最好将其完全作为查询或存储过程编写,这样就可以使用SQL引擎保证不会遗漏任何行。如果做不到这一点,您可能需要添加一个timestamp列来记录最后一次“处理”行的时间。或者您可以使用Sammitch所说的timestamp列。