我正在为利基行业建立一个基于网络的目录。我想在每个列表/个人资料上提供一个观看柜台,类似于MySpace在过去的好时光中使用它的方式(回到90年代的MySpace,一切都被原谅)。
我正在使用MySQL,并想知道记录数据的最佳方式是什么。
另一个帖子(What is the best way to count page views in PHP/MySQL?)由@dorkitude提供了以下解决方案:
$sample_rate = 100;
if(mt_rand(1,$sample_rate) == 1) {
$query = mysql_query(" UPDATE posts SET views = views + {$sample_rate} WHERE id = '{$id}' ");
// execute query, etc
}
这适用于概率论,并由@Suyash解释为
这背后的一般想法是,从理论上讲,应该花费100次尝试才能达到数字' 1' - 因此,在不需要查询数据库的情况下,视图计数或多或少是正确的。
这个帖子是2011年的日期,我想知道从那时起是否有任何更好的解决方案被曝光。
答案 0 :(得分:2)
首先,确保跟踪异步完成。在页面呈现期间不要执行跟踪。在页面加载后使用javascript调用跟踪脚本。
使用采样率肯定会有助于提高性能,但会降低较低音量的准确度,尤其是100的采样率。也许您可以在低计数时降低采样率。例如对于前1000个页面视图,跟踪每个视图(禁用采样)。之后使用100的采样率。不要通过查找mysql中的计数来执行此操作。在调用异步跟踪脚本时,您需要通过浏览量计数(或等效采样率)。
如果posts表中有大量记录,WHERE查找将增加开销。考虑在另一个专用跟踪表中插入跟踪记录。然后,您可以定期(每晚)通过汇总所有跟踪记录来更新posts.views。
您还可以考虑定期处理和聚合Web服务器日志的方法。这可能特别有效,因为您可能无论如何都要记录所有页面视图。
答案 1 :(得分:0)
下面的代码与您所引用的代码类似,但不是依赖概率来更新数据库,而是将计数存储在文件中,并在文件计数器达到某个数字时更新数据库。
它比你提到的方法慢,但它比为每个页面视图更新存储在数据库中的计数器更快,特别是在具有多个Web服务器和单个数据库的设置中。
$update_rate = 100;
$file = "/my_counters/page_view_counter_$id";
if(!file_exists($file)) {
file_put_contents($file,0);
}
$fp = fopen($file,"r+");
//acquire lock on counter file
//increment counter by 1
//if counter is equal to update rate, update count in db
//and reset counter to 0
if(flock($fp, LOCK_EX)) {
$count = fread($fp, filesize($file));
if(++$count >= $update_count) {
$count = 0;
}
rewind($fp);
fwrite($fp,$count);
flock($fp,LOCK_UN); //release lock on counter file
}
if($count == 0) {
$query = mysql_query(" UPDATE posts SET views = views + {$update_rate} WHERE id = '{$id}' ");
// execute query, etc
}