我想为我的游戏实现互联网高分。并向他们所拥有的玩家提供反馈(不仅仅是top100或类似的东西)。 在普通的SQL中,它看起来像这样:
SELECT COUNT(*)FROM得分WHERE积分> :newUsersPoints
和GQL有类似的东西
db.GqlQuery(“SELECT * FROM Score WHERE points>:1”,newUsersPoints).count()
但由于count()仅限于1000,因此在我的情况下它不会非常有用。 您对如何实现这一点有任何想法吗?
我有两个
首先:
使用分片计数器的想法(http://code.google.com/intl/pl/appengine/articles/sharding_counters.html) 创建新的“表格”,用于存储某些范围内的分数(from_points,to_points)
汇总上表中所有的计数器,其中range.to_points< newUsersPoints
查找有多少分数大于新分数范围内的分数 db.GqlQuery(“SELECT * FROM Score WHERE points>:1 AND points> =:2 AND points<:3”,newUsersPoints,range.from_points,range.to_points).count()+ sumfrom2
查找新分数所在的范围并增加其分数
分割范围哪个计数器大于1000(或999),以便3.不会达到极限
在分数表中添加新分数
这很复杂且容易出错。在添加分数之前,我们可能会增加一些范围和超时。 (不是交易)
第二个想法:
不时(每天一次?)按分数对所有分数进行排序并给他们新的位置(脚本可能超时,所以我们必须以块的形式进行)
要了解我们刚刚在哪个地方做新分数
db.GqlQuery(“SELECT * FROM Score WHERE points>:1 LIMIT 1”,newUsersPoints).get()。precalculated_position + 1
还有其他想法吗?
答案 0 :(得分:5)
我在几个GAE应用程序中实现了Ranker。他们是Facebook应用程序,有数千到数十万人在玩。它运作良好,但就我的目的而言,它有一个很大的缺点:你需要事先声明参与者得分落入的最终范围。所以这有两个原因:
如果你的比赛没有结束,人们的分数可以继续攀升而没有上限,你就会被吵闹。
在比赛开始时,当每个人在零附近聚集在一起时,ranker.py使用的树结构效率不高。树很深,几乎没有任何广度。
换句话说,如果您的参赛者的得分在一个已知的值范围内以均匀的方式随机分布,则ranker.py非常适合。对于其他用途,它不是最佳的。
我希望尽快开发一个更普遍有用的排名引擎。当发生这种情况时,肯定会更新这个帖子!
答案 1 :(得分:4)
这thread on the google-appengine group可能会引起人们的兴趣。它看起来还有一个库,ranklist,专门用于此。
基本上,听起来他们做了类似于分片计数器的事情。