我希望像大多数论坛,Youtube和其他几个论坛一样实施一个视图计数器。因此,每次用户阅读文章时,都会存储和记住。我也想知道是谁看了这篇文章。
我的问题是:你如何有效地实现这一目标?什么是最佳做法?
一种方法是为每个视图调用存储过程,但这会导致对数据库进行大量不必要的调用。
另一种方法是将它存储到某个全局应用程序对象,然后每隔5分钟左右存储在数据库中(你甚至可以这么做吗?)
最好的方法是什么?
答案 0 :(得分:4)
数据库操作非常便宜,真的不值得担心。如果数据库操作甚至非常昂贵,那么你总是可以将阻塞操作委托给一个新线程,从而释放你的页面生成线程(你可以轻松地为数据库中没有返回任何内容的UPDATE和INSERT操作执行此操作 - 它们无关紧要。)
Sprocs现在并不是真正的时尚 - 它们可能从预先计算的执行计划中获得的性能优势几乎被消除,因为现代服务器缓存来自所有先前查询的计划,并且对于简单的SELECT,INSERT和UPDATEs你开始遭受代码复杂性增加的困扰。现在内联SQL命令没有任何问题。
无论如何,回到主题和总结:你的假设是错误的。在每个页面视图上运行UPDATE Pages SET ViewCount = ViewCount + 1 WHERE PageId = @pageId
没有错。这样做也没有错:INSERT INTO UserPageviews (UserId, PageId, DateTime) VALUES ( @userId, @pageId, NOW() )
。这两种操作都非常便宜,即使是老旧的数据库服务器也会在2-3毫秒内执行。
答案 1 :(得分:1)
另一种方法是将其存储到某个全局应用程序对象, 然后每5分钟左右存储在数据库中(你甚至可以这样做 好的方式?)
除非使用持久排队机制(如MSMQ),否则此方法很容易丢失数据。除非你预计会有大量的流量,否则我甚至不会想到这种方法。
这种性质的写作很便宜,每秒数百次操作并不是什么大问题。我最近建立了一个评论/评级框架,仅在我的本地一体化工作站上实现每秒3000多个完整事务的吞吐量。这包括处理请求,验证以及在事务中创建多个记录。
作为一个说明,您应该采取措施确保您的统计数据不易受到人为通胀/操纵的影响。这部分过程可能比视图跟踪本身更复杂。例如,用户不应该坐下来按住F5键并夸大其视频的观看次数。这些值也不应该被HTTP操纵(例如,创建一个小脚本来反复发送AJAX请求)。
这表明每个INSERT前面都会有一个SELECT,以确保在某段时间内尚未记录相同的用户ID或IP。当然,这不是万无一失的(除非你付出了很多努力),但它在保守主义方面是错误的,这通常是一种很好的方法。
一种方法是为每个视图调用存储过程,但那样 会导致对数据库进行大量不必要的调用。
我经常要提醒自己(和其他开发者)不要害怕数据库。人们(包括我)有时会竭尽全力避免一些简单的数据库调用。保持你的表格狭窄和索引良好,这样的操作比你想象的要快。