我正在编写一个在cron上运行的PHP脚本,并从API [标题(文本),路径(文本),访问者(整数)]中提取JSON数据并将其存储在SQLite数据库中。每次运行时,如果它看到现有标题,它应该将新访客数量添加到现有访问者。如果没有,它应该将新数据添加为新行。
这是我的循环的简化外观:
foreach($results as $printresults) {
//this iterates though $title, $path and $visitors
$existing_visitors = $db->query("SELECT SUM(visitors) FROM topten WHERE
title='$title'");
while ($existing_vis_row = $existing_visitors->fetch(SQLITE_NUM)) {
$dupe_enter = $db->query("UPDATE topten SET title='$title', path='$path',
visitors='$existing_vis_row[0]' WHERE title='$title' ");
}
$db->query("INSERT INTO topten (id,title,path,visitors,time) VALUES
(NULL, '$title', '$path', '$visitors', '$time');");
}
然后我会执行SELECT
来提取访问者排序的DISTINCT
行并将其写入文件。由于UPDATE
查询会将所有访问者添加到这些行中,因此所有欺骗都无关紧要。在某个超时时间,我将丢弃整个表并再次开始收集,因此文件不会太笨重。
问题在于它在循环的每次传递中添加总计访问者计数,使得访问者完全没有重击。但是我无法找到一种更好的方法来在每次运行脚本时简单地将数据添加到一起。
答案 0 :(得分:1)
伪码:
for($json_records as $rec){
$row = SELECT visitors FROM topten WHERE title = $rec['title']
if($row)
//record exists, add visitors and update
$sum_visitors = $row['visitors'] + $rec['visitors']
UPDATE topten SET visitors = $sum_visitors WHERE title = $rec['title']
else
//record doesn't exist, insert new
INSERT topten (title, visitors) VALUES ($rec['title'], $rec['visitors'])
}
也许?
答案 1 :(得分:0)
INSERT OR REPLACE ...
而不是自己动手。
像CREATE UNIQUE INDEX 'title_path' ON topten (title, path)
这样的东西。这将使两个具有相同标题和路径字段的记录变得不可能。所以,如果你只是盲目INSERT ....
,如果它是一个骗局你就会遇到冲突错误。
所以,只需使用INSERT OR REPLACE ....
,这将首先检查任何唯一索引,如果已经有记录,它将被删除,然后它将执行插入。当然它都是原子的(因此其他过程检查不会看到记录消失并重新出现)。