非关系数据库(NoSQL)中的排名(分数)建模

时间:2012-12-11 22:58:26

标签: google-app-engine database-design nosql ranking amazon-simpledb

我正在使用Google App Engine,所以我使用的是非关系型数据库(NoSQL)。我的问题是:

使用他们的分数对排名(球员排名)进行建模的最佳选择是什么?

例如,我的玩家是:

Player { String name, int score}

我想知道一名球员的排名(位置)并获得前10名选手,但我怀疑哪种选择最好。

感谢。

4 个答案:

答案 0 :(得分:2)

如果您的分数已编入索引,则可以轻松执行数据存储区查询并按顺序排列玩家。 所以,如果你想要前十名球员,这是非常微不足道的。

获得任意玩家的排名真的很难。我已经说过了,如果可以的话,尽量避免使用它,如果你不能,就找到一个黑客的方法。

例如,如果您有50,000名玩家,并且PlayerX排名为12,345,那么了解它的唯一方法是查询所有玩家,并检查每个玩家,保持计数,直到找到PlayerX。

一个hack可能是将玩家排名存储在玩家实体中,并使用每隔几个小时运行一次的cron作业进行更新。

答案 1 :(得分:1)

Redis中有一个内置解决方案:

首先添加一些得分为

的成员
redis>  ZADD myzset 1 "one"
(integer) 1
redis>  ZADD myzset 2 "two"
(integer) 1
redis>  ZADD myzset 3 "three"
(integer) 1

获得“两个”的排名:

redis>  ZREVRANK myzset "one"
(integer) 2

(指数从0开始)

如果你想要当前的订单:

redis>  ZREVRANGE myzset 0 -1
1) "three"
2) "two"
3) "one"

请参阅redis文档中的ZREVRANGEZREVRANK

答案 2 :(得分:0)

在JSON中合适的表示形式是:

"players" : [
    {
        "name" : "John",
        "score" : 15
    },
    {
        "name" : "Swadq",
        "score" : 7
    },
    {
        "name" : "Jane",
        "score" : 22
    }
]

有关如何对此进行排序的示例:

答案 3 :(得分:0)

您可以像这样设置index.yaml:

- kind: Player
  properties:
  -  name: score
     direction: ascending

要获得玩家的分数,您只需要对玩家进行传球(同时保持计数)并缓存结果以加快搜索该玩家的速度。