我正在考虑创建自己的GAE应用来跟踪玩家在我的电子游戏中的高分。我已经创建了一个简单的应用程序,允许我发送和恢复前10名的高分(即每场比赛只存储10个分数),但现在我考虑成本如果事情增长。
说游戏中有成千上万的玩家(呵呵,不是我的)。我已经看到像OpenFeint这样的应用程序如何能够对您的分数进行排序,并在具有数千个条目的高分表中告知您的确切排名。例如,你可能是#19623。
为了简单起见,我会创建前100名的得分表。但是,如果我真的想要存储所有分数并保持排序,该怎么办?在数据库中查询分数时,简单地对分数进行排序是否有意义?我不这么认为......
这些应用程序是如何实现的?
答案 0 :(得分:1)
在GAE上,只要您索引字段,就可以轻松返回已排序的查询。如果您的目标只是找到前100个分数,您可以按分数对100个实体进行有序查询 - 您将按顺序获得它们。
https://developers.google.com/appengine/docs/python/datastore/queryclass#Query_order
更难的部分是为查询分配号码。对于前100名,您基本上会查看返回的100个实体列表,并在每个实体旁边打印一个数字。
如果您需要找到特定排名的用户,您可以使用光标缩小搜索范围以说明排名第19623位的用户。
你无法有效地做到这一点就是弄清楚单个实体的等级。为了使用内置索引计算排名,您必须查询所有实体,并找到该单个实体在列表中的位置。
排名最懒的方式就是搜索前100名,如果用户在那里,显示他们的排名,如果没有,那么告诉他们他们是> 100.另一种可能性是偶尔进行大量查询以获得分数范围,存储分数范围,然后给用户一个较少的累积(你在前500名,前1000名等),而没有确切的位置。
答案 1 :(得分:1)
标准数据库索引 - 在App Engine和其他地方 - 都没有提供查找行/实体等级的有效方法。一种选择是定期浏览数据库并更新当前排名。但是,如果您希望立即更新排名,则基于树的解决方案会更好。在app-engine-ranklist项目中为App Engine提供了一个。
答案 2 :(得分:1)
我们在TyprX打字比赛(GWT + App Engine)时遇到了同样的问题。我们这样做的方式没有通过数百万行来存储高分,如下所示:
class User {
Integer day, month, year;
Integer highscoreOfTheDay;
Integer highscoreOfMonth;
Integer highscoreOfTheYear;
}
这样,您可以查询每日,每月,每年高分的排序列表。关键是在完成游戏时用每个时期的最佳分数更新用户记录。
然后我们添加了将结果保存到memcache和voila。
丹尼尔
答案 3 :(得分:1)
我考虑使用异常处理。每天每小时数千个结果中有多少会成为前100名?保持最小/最大前100个范围实体(当然是memcached)。如果它在范围内,则每个得分都是一个方向,否则是另一个方向(任务队列?)。为什么不将99%的不相关工作分流到另一个流程,只需要处理100 + 1 recs,无论你的最终设置是什么,都可以改变排名。