ruby-on-rails - 实现排行榜

标签 ruby-on-rails leaderboard

用户 on my site为说唱歌词创建注释 ( example )。我想创建一个排行榜来奖励创建最多注释的人。

排行榜应该跟踪每个用户总共创建了多少注释,以及他在过去一周、一天等中创建了多少注释。

我在实现整体排行榜时没有问题:

@users = User.all

<table>
  <tr>
    <th>Contributor</th>
    <th>Annotations</th>
  </tr>
    <% @users.sort_by{|u| u.annotations.size }.reverse.each do |u| %>
      <tr>
        <td><%= u %></td>
        <td><%= u.annotations.size %></td>
      </tr>
    <% end %>
</table>

但是当我尝试实现(比如)每日记分板时,我正在重复代码并且操作非常缓慢(因为它必须遍历内存中的每个注释而不是依赖数据库排序/计数):
<table>
  <tr>
    <th>Contributor</th>
    <th>Annotations</th>
  </tr>
    <% @users.sort_by{|u| u.annotations.select{|a| a.created_at > 1.day.ago }.size }.reverse.each do |u| %>
      <tr>
        <td><%= u %></td>
        <td><%= u.annotations.select{|a| a.created_at > 1.day.ago }.size %></td>
      </tr>
    <% end %>
</table>

实现每日/每周记分牌的最佳方法是什么?

最佳答案

排行榜作为一个整体来说实现起来很痛苦。嗯,根据我的经验,实际的实现是相当简单的,只是它们很难扩展。通常,您发现自己必须运行许多数据库查询,这些查询非常密集。要处理每日/每周报告,人们可能会查询日期时间列,但这意味着您在所述列上有一个索引。该索引实际上仅对排行榜查询有用,并且它使该表上的所有其他写入付出代价,因为必须重新计算索引。

另一种方法是按计划的时间间隔生成统计信息,然后将该数据写入单独的表,供排行榜查询使用。例如,您有一个每天晚上运行的后台作业,您运行一个查询(可能它是一个昂贵的一个,因为它不使用日期时间索引,但由于它只运行一次并且通过后台作业,费用是“确定”的),该查询依次写入 的统计表在日期时间列上有一个索引,然后你重写你的排行榜页面来达到你预先计算的统计数据。根据您的需要,您可能让 cron 脚本还进行其他数据处理和预计算,因此排行榜页面必须根据需要进行尽可能少的计算。

在这一点上,您的排行榜页面可以正常工作,当它访问一个带有索引的表时,它仍然需要读取大量行。这是假设您有不错的流量。让索引查询在每个页面上都命中大量行仍然很昂贵。所以现在你考虑实现页面缓存,也许将数据存储在 memcached 中。也就是说,由于每日排行榜数据至少每天都在变化,根据定义,在每个页面 View 上重新运行这些数据库查询的成本很高。将日常数据缓存在 memcached 中更有意义,并且每个页面 View 只访问 memcached。

所以你可以看到它是一个进化的过程。如果您的流量低于您可能没有单独的表而只有在日期时间列上有索引的情况。运行总和、计数和平均值可能没问题。但它没有规模。因此,您必须考虑将其分解为更优化的结构。然后你会看到每天一遍又一遍地运行相同的查询而底层数据在 24 小时内不会改变是昂贵的,所以你转向缓存设置。有很多事件部件,它可能会变得复杂,嗯,真的只是乏味的快速。

当谈到排行榜时,我是一个久经沙场的愤世嫉俗者,虽然它们非常适合游戏机制和激励人们(每个人都喜欢看到分数!),但大规模开展工作是一件很痛苦的事情。

关于ruby-on-rails - 实现排行榜,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1992608/

相关文章:

ruby-on-rails - 生产中的 Rails Assets 出现问题

android - 如何使用 Google Play 服务 C++ 实现前 10 名排行榜

ios - 如何显示所有可用的 Game Center 排行榜,而不是自动显示默认排行榜?

ruby-on-rails - Rails Geocoder 限制地区/国家

ruby-on-rails - 测试配方 : How to test a ruby gem with rails dependencies

ruby-on-rails - 用于生产的扭矩箱。任何人?

ruby-on-rails - Redmine/Rails - 发送 POST 数据时未定义的方法

ios - 如何在项目中实现排行榜(游戏中心)

python - Redis 在给定分数附近获取用户集

MySQL 排名与表中的高分不匹配