【问题标题】:How to convert "top 10" list from SQL to NoSQL如何将“前 10”列表从 SQL 转换为 NoSQL
【发布时间】:2012-09-11 07:10:33
【问题描述】:

我有一个正在使用 MySQL 的在线游戏。我有一个如下所示的 Player 表:

create table player (
    id integer primary key,
    name varchar(50),
    score integer
);

我在“分数”列上有一个索引,并显示如下排名:

select id, name, score from player order by score desc limit 100

我想将我的系统迁移到 Redis(或者,如果其他 NoSQL 更适用于此类问题,请告知)。所以我想知道有什么方法可以有效地展示这种排名表?

AFAICT,这可能是 Map/Reduce 工作吗?我对 Map/Reduce 几乎一无所知,尽管我阅读了一些我仍然不太了解的文档,因为我无法找到任何现实生活中的示例。

谁能给我一个粗略的例子,如何在 Redis 中进行上述查询?

【问题讨论】:

标签: mysql nosql redis ranking


【解决方案1】:

在 redis 中,您可以使用排序集 (http://redis.io/commands#sorted_set) 当您在排序集中对项目进行评分后,您可以通过调用 ZRANGE players 0 N 获得前 N 个

【讨论】:

  • 看起来不错。一个问题:如果我需要有多个排名(比如:score和monthly_score),我需要创建两个集合吗?
  • 是的,对于每个分数。或者如果monthly_score 取决于得分,我认为您可以为每个玩家使用list 来为他的得分历史加注星标
【解决方案2】:

好问题 - 在 MongoDB 中,您必须使用 group() 函数来返回这种类型的查询:

select id, name, score from player order by score desc limit 100

可能看起来像这样:

db.player.group(
           {key: { id:true, name:true },
            reduce: function(obj,prev) { if(prev.cmax<obj.score) prev.cmax = obj.score; },
            initial: { cmax: 0 } // some initial value
            });

使用基于 MapReduce 的方法可能是最好的,请参阅:

【讨论】:

  • 谢谢。这种功能的效率如何?我在那个 Player 表中有大约 1000 万条记录。会不会遍历Map过程中的所有记录?
  • 嗯,是的,在这种情况下,它确实必须遍历整个数据集。我认为最好的解决方案可能是在 MapReduce 之前先过滤您的数据集 - 例如,从得分超过“50”或其他东西的所有玩家开始。否则,“效率”将始终相同,但速度取决于您使用的系统 - 如果您的 NoSQL 分布在多台机器上,则 Map 和 Reduce 可以在网络上的各种服务器上进行。跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-08
  • 1970-01-01
  • 2022-11-16
  • 1970-01-01
  • 2018-10-19
相关资源
最近更新 更多