我想知道如何在我的数据库中最好地实现“访问次数最多”功能(如youtube)。
让我更好地解释“观看次数最多”功能: 基本上我想从这一天/周/月列出访问量最大的页面/视频/等,请参阅 http://www.youtube.com/charts/videos_views举个例子。
所以我想知道如何最好地实现这个功能,因为我可以想到许多方法,但他们都有+和 - 给他们。
另外,我也很想听到各种程序员对其他程序员想法的评论。我也想就这个话题开始一个很好的对话。
聚苯乙烯。我正在特别关注如何计算时间,比如本月最常见的时间,而没有一个巨大的表格,可以用日期时间保存每个视图。任何想法都是受欢迎的。
PPS。我使用Mysql和PHP,非常欢迎这两个的额外提示。
答案 0 :(得分:3)
有以下表格: 1.观点 2. views_hourly_summary 3. views_daily_summary 4. views_monthly_summary 5. views_alltime_summary
按以下时间间隔运行cron作业:
每小时运行一次,并从views表中预聚合该小时的视图,并将预先聚合的结果保存在views_hourly_summary表中,同时更新views_alltime_summary表
在每天结束时运行,并从小时表中预先聚合当天的视图,并将预先聚合的结果保存在views_daily_summary表中
在每个月末运行,并从小时表中预先聚合当天的视图,并将预先聚合的结果保存在views_daily_summary表中
接下来,在获取结果时,您将需要进行如下计算:
例如,您想要获取最近4个小时的视图,您将从每小时表中获取3个整数小时数据,剩余数据从视图表中获取,如下所示:
选择item_id,sum(views)作为视图 来自views_hourly_summary concat之间的小时(左(现在() - 间隔3小时,14),'00:00')和concat(左(现在(),14),'00:00') 按item_id分组
联合
选择item_id,将count(1)视为视图 来自观点 其中datetime(now() - interval 4 hour)和concat(left(now() - interval 3 hour,14),'00:00') 或日期时间> concat(左(现在(),14),'00:00') 按项目分组
答案 1 :(得分:1)
首先,我尝试使用Cookie跟踪用户,为他们提供一个唯一ID作为访问和访问。这应该有助于识别。
我尝试移动逻辑以更新网站代码库中最常查看的项目。所以这只是意味着每个Web请求都将访问信息发布到消息队列 - 可能包括时间/日期,正在查看的项目,来自cookie的跟踪信息以及可能的IP地址/请求标题。
然后我会设置一个服务来从该队列中读取并处理信息。这将允许您在不影响站点的情况下升级/修改该逻辑。您可能希望处理多次刷新等,以阻止人们弄乱结果 - 无论是有意还是无意。此外,通过将此处理从主站点中抽象出来,您不会减慢页面请求时间 - 您可以根据需要使逻辑确定/更新项目视图的复杂程度。
答案 2 :(得分:1)
我想到的简单方法是为加载该页面的用户的每个唯一IP将表上的ViewCount字段值增加1。
答案 3 :(得分:0)
在我的头顶,我会有一个ItemViews表,它将视图的数量映射到一个项目ID(假设只有一个项目类型)。该表可以有2列:ItemId和ViewCount。当一个新特性收到它的第一个视图时,我会在该表中插入一个新行并将ViewCount初始化为0.然后,每当我检测到一个新视图时,我都会在该行中递增计数器。
然后我可以从该表中计算统计数据。如果有类别的概念(比如在Youtube中),我可以使用ItemId加入类别ID,并将我的视图分组。
答案 4 :(得分:0)
这是一个非常简单的解决方案。它不是完全最优的,但可以在没有太多悲伤的情况下得到改善。
基本上只是把时间分成几个间隔,比如每个5分钟。在db中有一个记录,其中一列用于videoID,一列用于标识特定时间间隔,然后一列用于显示该视频在该时间间隔内获得的视图数。然后,如果你想知道一个视频在最后一天获得了多少观看次数,只需将所有那些视图加上间隔/时间戳大于一天的位置。它并不是完全最优的,因为最后一个区间只会部分填充视图,这会为您提供一些额外时间或稍微少一些时间的视图,具体取决于您何时计算它。但对于需要两秒钟制作的解决方案来说,这已经足够了。要计算年度视图,请执行相同的操作,除非使用完全独立的表格,其中时间间隔为1天,因此您不必存储数据并总计超过100,000个五分钟的时间间隔来完整年。
确保在[videoId,timestamp]上有一个复合索引,以便您可以快速总结视图。