我正在实施一个应用程序,可以跟踪帖子的查看次数。但我想保持一种“聪明”的跟踪方式。这意味着,我不想仅仅因为用户刷新浏览器而增加视图计数器。
因此,如果IP和用户代理(浏览器)是唯一的,我决定只增加视图计数器。到目前为止哪个是有效的。
但后来我想。如果Youtube正在这样做,他们有几个视频有数千甚至数百万的视图。这意味着他们在数据库中的视图表将过多地填充IP和用户代理....
这使我假设他们的视频表具有视图的计数器缓存(即views_count
)。这意味着,当用户点击视频时,将存储IP和用户代理。此外,视频表中的计数器缓存列也会增加。
每次点击视频。 Youtube需要查询视图表并计算条目数。这不会对性能造成太大影响吗?
这是他们这样做的吗?或者有更好的方法吗?
答案 0 :(得分:1)
如果您想存储所有IP和浏览器,请确保您有足够的数据库存储空间,添加索引就可以了。 如果没有,那么您可以使用rails会话来存储用户访问过的视频列表,并且只在访问新视频时增加视频的view_count属性。
答案 1 :(得分:1)
首先,afaik,youtube使用BigTable,所以不要担心查询计数,我们无论如何都不知道数据库的确切结构。
假设您使用的是关系模型,请创建列view_count,但不要在每次刷新时更新它。记录访问者并定期更新缓存。
此外,您可以从IP,浏览器,日期以及用于检测这是否是唯一视图的任何其他信息生成哈希值,并且不存储整个数据。
此外,您可以使用session / cookie记录正在查看的视图。由于它将过期,它不会是这样的记忆问题 - 我不相信任何人在一次会议中观看数千个视频
答案 2 :(得分:1)
我会利用客户端浏览器指纹识别来唯一地识别视图计数。这个图书馆似乎有了很大的吸引力:
https://github.com/Valve/fingerprintJS
我还建议使用Redis处理与计数有关的任何事情。它的原子增量命令易于使用,并保证您的计数永远不会因竞争条件而搞砸。
这将是您希望用于递增计数器的命令:
这种情况下的密钥是从客户端发送给您的浏览器指纹哈希。然后,您可以使用Redis“set”,其中包含已知与给定user_id相关联的所有浏览器指纹的列表(该组的键将是user_id)。
最后,如果您确实需要,则运行cron作业或其他异步进程,将每个用户的视图计数转储到关系数据库的计数器缓存字段中。
您还可以采用在关系数据库(mysql?)中存储user_id,浏览器指纹和时间戳的方法,并定期将它们缓存到用户表中(可能通过cron)。