如何“查看计数”最佳实施?

时间:2009-06-03 10:09:58

标签: database-design schema

在任何网站上,例如在StackOverflow上,每个问题都有一个视图计数,而用户在阅读问题但之前已经阅读过它将不会计算两次。

我对如何实现它以及使用哪些表来实现它有一些想法。

您认为实施此方法的最佳方式是什么?

6 个答案:

答案 0 :(得分:10)

我看到你有几个选择。

<强>缓存

您可以在用户浏览器中为要记录视图的每个页面存储Cookie。检查此cookie是否存在,如果cookie已存在,则不记录视图。

缺点是,如果禁用cookie或有人试图对系统进行游戏,它将无效。

从好的方面来说,您不必担心存储数百万/数十亿行表数据。

<强>数据库

您为每个视图保留一条记录。以某种方式将该记录与用户相关联,例如会员ID,IP地址;对用户来说应该是唯一的东西。如果您不要求用户登录,IP并不理想,但足够好。

因此,您将拥有一个包含以下列的表

  • ArticleID(外键)
  • UserID(外键)
  • 日期

由于几个原因,日期将有用,

  • 报告。一旦知道记录每个视图的时间,就可以构建更好的统计数据。
  • 查看超时。例如,您可能只想每个用户每小时存储一个视图。保持日期列可以执行此操作。

如果您的应用程序在这种情况下变得流行,那么您将需要处理存储问题。我运行一个流行的Facebook应用程序,每天会添加超过100,000个视图行。实际上,如果你的应用程序变得如此受欢迎以至于它成为一个问题,那么你将面临更大的问题需要处理。

答案 1 :(得分:10)

在我的网站上,我通过使用随机数划分视图数来处理客户视图和“大量数据”。

假设我有一个0到1之间分布良好的随机数生成器,我每天在特定页面上获得100,000个视图。如果我在每个视图中调用'logView()'函数,但在其中生成一个新的随机数,并且只有在随机数为&lt;时才将视图真正记录到数据库中。 0.001,然后对于100,000次观看,我只会命中DB大约100,000 * 0.001 = 1000次。

如果我想返回一个视图计数,那么我只是将我的DB编号除以相同的值,例如。 1000 / 0.001 = 100,000。这近似精确到最接近的1000个视图。

显然,您可以选择一个取决于您网站负载的随机数范围,如果您的负载发生显着变化,您甚至可以更改此选项(您只需要相应地修改存储的值)。

此外,只有1000个视图的页面在视图计数中甚至可能得不到1,但如果您有一个包含100,000个视图的页面,那么1000个视图的页面非常微不足道。

答案 2 :(得分:3)

简短回答:这取决于!

  • 这实际上取决于你需要多少准确的观看次数,是否可以接受一个人注册两到三次?
  • 这取决于您要使用的数据。如果您想对数据(统计信息,最近查看列表等)做其他整洁的事情,您可能需要考虑将所有单个视图存储在数据库中。这可能会导致巨大的表,因此您必须在实现它之前解决这个问题。

我之前使用过Cookie和内存数据库来存储个人视图(出于显而易见的原因,我将实际视图计数存储在数据库表中,并持久保存到磁盘)。我可以做到这一点,因为统计数据没有任何意义。

答案 3 :(得分:1)

当您网站的大多数访问者注册时,相对容易确保其中没有一个被计算两次。

我不确定SO是否会计算客人的观点。我想我可以检查但是已经很晚了。

答案 4 :(得分:1)

看起来stackoverflow不会计算查看主题的访客(未记录)用户。计算匿名用户视图的问题是您的计数器可以被游戏。有人可以随时删除cookie并再次查看。记录视图是最安全的准确性解决方案,但当然您有两个主要问题:表的大小和缺少访客/匿名用户。令我惊讶的是,stackoverflow没有记录访客(未记录)用户。我认为大多数观点都来自这些用户进行谷歌搜索。

答案 5 :(得分:0)

我会尝试从功能的角度给出答案。

为每个用户计算视图 - 对于注册用户。对于匿名用户 - 每个会话。

在观看该项目的其他人进行重大更新后,第一个视图和任何视图上的视图计数增加。

创作时海报的视图不应计算

你可以想象做得更简单,但我试着想出一个理想的解决方案。