2

我想像大多数论坛、Youtube 和其他几个论坛一样实现一个视图计数器。因此,每次用户阅读一篇文章时,它都会被存储和记住。我也想知道谁看了这篇文章。

我的问题是:你如何有效地实现这一点?最佳做法是什么?

一种方法是为每个视图调用一个存储过程,但这会导致对数据库进行大量不必要的调用

另一种方法是将其存储到某个全局应用程序对象中,然后每 5 分钟左右存储在数据库中(您甚至可以以一种好的方式做到这一点吗?)

最好的方法是什么?

4

2 回答 2

4

数据库操作非常便宜,真的不值得担心。如果 DB 操作稍微昂贵,那么您总是可以将阻塞操作委托给一个新线程,从而释放您的页面生成线程(对于从数据库中不返回任何内容的 UPDATE 和 INSERT 操作,您可以轻松地执行此操作 -它们无关紧要)。

Sprocs 现在并不是真正的时尚——它们可能从预先计算的执行计划中获得的性能优势几乎被消除了,因为现代服务器缓存了所有先前查询的计划,并且对于琐碎的 SELECT、INSERT 和 UPDATE,您开始遭受痛苦由于代码复杂性增加。现在内联 SQL 命令没有任何问题。

无论如何,回到主题并总结一下:您的假设是错误的。UPDATE Pages SET ViewCount = ViewCount + 1 WHERE PageId = @pageId在每个页面视图上运行都没有错。这样做也没有错:INSERT INTO UserPageviews (UserId, PageId, DateTime) VALUES ( @userId, @pageId, NOW() ). 这两种操作都非常便宜,即使在旧的和老化的数据库服务器上也能在 2-3 毫秒内执行。

于 2012-09-23T22:18:16.747 回答
1

另一种方法是将其存储到某个全局应用程序对象中,然后每 5 分钟左右存储在数据库中(您甚至可以以一种好的方式做到这一点吗?)

除非您使用持久的排队机制(如 MSMQ),否则此方法很容易丢失数据。除非您预计会有大量流量,否则我什至不会考虑这种方法。

这种性质的写入成本很低,每秒数百次操作也没什么大不了的。我最近构建了一个评论/评级框架,仅在我的本地一体化工作站上就可以实现每秒 3000 多个完整事务的吞吐量。这包括处理请求、验证和在事务中创建多个记录。

请注意,您应该采取措施确保您的统计数据不易受到人为膨胀/操纵的影响。这部分过程可能比视图跟踪本身更复杂。例如,用户不应该坐下来按住 F5 键并夸大其视频的观看次数。这些值也不应该被 HTTP 操纵(例如,创建一个小脚本来一遍又一遍地发送 AJAX 请求)。

这表明每个 INSERT 之前都会有一个 SELECT,以确保在某个时间段内没有记录相同的用户 ID 或 IP。当然,这并不是万无一失的(除非您投入大量精力),但它偏向保守主义,这通常是一种好方法。

一种方法是为每个视图调用一个存储过程,但这会导致对数据库进行大量不必要的调用。

我必须经常提醒自己(和其他开发人员)不要害怕数据库。人们(包括我)有时会竭尽全力避免一些简单的数据库调用。保持你的表窄且索引良好,这样的操作比你想象的要快。

于 2012-09-23T22:28:36.023 回答