我的数据库有600多行,但每小时只能检索/显示100行。所以我用
select * from table ORDER BY id DESC LIMIT 100
检索前100个。如何编写一个脚本,该脚本每1个小时将以100个批次检索数据,以便可以在cron作业中使用它?
可能的解决方案。
ALTER TABLE tablename
ADD COLUMN shown TINYINT NULL DEFAULT NULL;
NULL将表示未选择该记录,1-该记录被标记为选择,0-该记录已被选择。
2.1。标记要显示的记录
UPDATE tablename
SET shown = 1
WHERE shown = 1
OR shown IS NULL
ORDER BY shown = 1 DESC, id ASC
LIMIT 100;
shown = 1
条件在WHERE中考虑了以下事实:某些记录已标记但由于某些错误而未被选择。 shown = 1 DESC
在未标记之前将这些记录重新标记。
如果未选择的记录少于100条,将全部标记,否则将仅标记ID较低(最古老)的100条记录。
2.2。选择标记的记录。
SELECT *
FROM tablename
WHERE shown = 1
ORDER BY id
LIMIT 100;
2.3。标记选定的记录。
UPDATE tablename
SET shown = 0
WHERE shown = 1
ORDER BY id
LIMIT 100;
仅当一个客户端选择记录时适用。
如果很多客户可以并行工作,并且只有一个客户必须选择一条记录,则使用一些客户编号(在所有客户中都是唯一的)来标记要选择的记录,而不是1
。
当然,如果只有一个客户端,并且保证选择不会失败,则可以将最后显示的ID存储在某个位置(在客户端,或者在MySQL端的某些服务表中),然后选择“下一个100 “从此存储的ID开始:
SELECT *
FROM tablename
WHERE id > @stored_id
ORDER BY id
LIMIT 100;
和
SELECT MAX(id)
FROM tablename
WHERE id > @stored_id
ORDER BY id
LIMIT 100;
用于存储而不是以前的@stored_id
。
比方说,您创建了一个cron,它点击了类似以下的URL
http://yourdomain.com/fetch-rows
或例如脚本,例如
your_project_folder/fetch-rows.php
假设您有一个看起来像这样的数据库表:
| id | offset | created_at |
|----|--------|---------------------|
| 1 | 100 | 2019-01-08 03:15:00 |
| 2 | 200 | 2019-01-08 04:15:00 |
您的脚本:
<?php
define('FETCH_LIMIT',100);
$conn = mysqli_connect(....); // connect to DB
$result = mysqli_query($conn,"select * from cron_hit_table where id = (select max(id) from cron_hit_table)")); // select the last record to get the latest offset
$offset = 0; // initial default offset
if(mysqli_num_rows($result) > 0){
$offset = intval(mysqli_fetch_assoc($result)['offset']);
}
// Now, hit your query with $offset included
$result = mysqli_query($conn,"select * from table ORDER BY id DESC LIMIT $offset,100");
while($row = mysqli_fetch_assoc($result)){
// your data processing
}
// insert new row to store next offset for next cron hit
$offset += FETCH_LIMIT; // increment current offset
mysqli_query($conn,"insert into cron_hit_table(offset) values($offset)"); // because ID would be auto increment and created_at would have default value as current_timestamp
mysqli_close($conn);
[cron命中时,您将从命中表中获取最后一行以获取偏移量。用该偏移量命中查询,并将下一个偏移量存储在表中。
感谢@Akina和@ Vivek_23的贡献。我能够找到一种更简单的方法。
缺点是,每天最多只能显示2,400条记录。即。每小时24小时每小时100条记录。因此,如果您的记录增长到大约10,000。您需要将cronjob设置为至少运行5天才能显示所有记录。
如果有的话,仍然可以寻求更好的方法,但是在那之前,我将不得不暂时坚持下去。