我想实现一个视图计数器,像大多数论坛,Youtube和其他几个有。因此,每次用户读到一篇文章时,都会存储并记住它。我也想知道是谁看了这篇文章。
我的问题是:如何有效地实现这一点?什么是最佳实践?
一种方法是为每个视图调用一个存储过程,但这将导致对数据库进行大量不必要的调用。
另一种方法是将其存储到某个全局应用程序对象中,然后每隔5分钟在DB中存储一次(您甚至可以这样做吗?)
做这件事最好的方法是什么?
发布于 2012-09-23 22:18:16
数据库操作非常便宜,真的不值得担心。如果DB操作的开销较小,那么始终可以将阻塞操作委托给一个新线程,从而释放页面生成线程(您可以为更新和插入从数据库中不返回任何内容的操作(它们是无关紧要的)做这件事。
Sprocs现在并不流行,它们可能从预先计算的执行计划中获得的性能优势几乎被消除了,因为现代服务器从以前的所有查询中缓存计划,对于琐碎的选择、插入和更新,您开始受到代码复杂性增加的影响。内联SQL命令现在没有什么问题。
总之,回到话题和总结:你的假设是错误的。在每个页面视图上运行UPDATE Pages SET ViewCount = ViewCount + 1 WHERE PageId = @pageId没有什么问题。这样做也没有什么错:INSERT INTO UserPageviews (UserId, PageId, DateTime) VALUES ( @userId, @pageId, NOW() )。这两种操作都非常便宜,甚至在老旧的数据库服务器上也能在2-3毫秒内执行。
发布于 2012-09-23 22:28:36
另一种方法是将其存储到某个全局应用程序对象中,然后每隔5分钟在DB中存储一次(您甚至可以这样做吗?)
除非使用持久的排队机制(如MSMQ),否则此方法很容易丢失数据。除非你预见到大量的交通,否则我甚至不会考虑这种方法。
这种性质的写作成本不高,每秒数百次操作并不是什么大事。我最近构建了一个评论/评级框架,它仅在本地的全合一工作站上就可以每秒完成3000+事务的吞吐量。这包括处理请求、验证和在事务中创建多个记录。
请注意,您应该采取步骤,确保您的统计数据不会受到人为通货膨胀/操纵的影响。这个过程的这一部分可能比视图跟踪本身更复杂。例如,用户不应该能够坐下来按住F5键并膨胀其视频上的视图数。HTTP也不应该操纵这些值(例如,创建一个小脚本来一次又一次地发送AJAX请求)。
这意味着每次插入之前都会有一个SELECT,以确保在一段时间内没有记录相同的用户ID或IP。当然,这并不是万无一失的(除非你投入了大量的努力),但它偏袒保守主义,而保守主义通常是一种很好的方法。
一种方法是为每个视图调用一个存储过程,但这将导致大量不必要的对数据库的调用。
我必须经常提醒自己(和其他开发人员)不要害怕数据库。人们(包括我)有时会不遗余力地避免几个简单的数据库调用。保持您的表的狭窄和良好的索引,这样的操作比您想象的要快。
https://stackoverflow.com/questions/12556367
复制相似问题