0

我正在考虑创建自己的 GAE 应用程序来跟踪玩家在我的电子游戏中的高分。我已经创建了一个简单的应用程序,它允许我发送和恢复前 10 名高分(也就是说,每场比赛只存储 10 个分数),但现在我正在考虑如果事情增长的成本。

假设一个游戏有成千上万的玩家(呵呵,不是我的)。我已经看到像 OpenFeint 这样的应用程序如何能够对您的分数进行排序,并在包含数千个条目的高分表中告诉您确切的排名。例如,您可能是#19623。

为了简单起见,我将创建前 100 名得分表。但是,如果我真的想存储所有分数并保持排序呢?在从数据库中查询分数时简单地对分数进行排序是否有意义?我不这么认为...

这些应用程序是如何实现的?

4

4 回答 4

1

在 GAE 上,只要您为字段编制索引,就很容易返回排序查询。如果您的目标只是找到前 100 个分数,您可以按分数对 100 个实体进行有序查询 - 您将按顺序获得它们。

https://developers.google.com/appengine/docs/python/datastore/queryclass#Query_order

更难的部分是将数字分配给查询。对于前 100 个实体,您基本上会遍历返回的 100 个实体列表,并在每个实体旁边打印一个数字。

如果您需要查找特定排名的用户,您可以使用光标缩小搜索范围,说出排名#19623 的用户。

你将无法有效地做的是找出单个实体的等级。为了使用内置索引计算排名,您必须查询所有实体,并找到该单个实体在列表中的位置。

进行排名的最懒惰的方法是搜索前 100 名,如果用户在那里,显示他们的排名,如果没有,然后告诉他们他们 > 100。另一种可能性是偶尔进行大查询以获得分数范围,存储这些,然后给用户一个不太准确的(你在前 500 名,前 1000 名等),而没有确切的位置。

于 2012-05-24T15:16:05.083 回答
1

标准数据库索引——无论是在 App Engine 还是在其他地方——都没有提供一种有效的方法来查找行/实体的排名。一种选择是定期浏览数据库并更新当前排名。但是,如果您希望立即更新排名,基于树的解决方案会更好。在app-engine-ranklist项目中为 App Engine 提供了一个。

于 2012-05-25T05:51:38.473 回答
1

TyprX 打字比赛(GWT + App Engine)也有同样的问题。我们没有经过数百万行来存储高分的方式是这样的:

  class User {

    Integer day, month, year;
    Integer highscoreOfTheDay;
    Integer highscoreOfMonth;
    Integer highscoreOfTheYear;

  }

这样做您可以通过查询获得每日、每月、每年高分的排序列表。关键是在用户完成游戏时,用他们自己在每个时期的最好成绩来更新他们的记录。

然后我们将结果保存到内存缓存中,瞧。

丹尼尔

于 2012-05-25T09:04:29.960 回答
1

我会考虑使用异常处理。每天/每小时的数千个结果中有多少会是前 100 名?保留一个最小/最大前 100 个范围实体(当然是 memcached)。如果在范围内,每个得分都是一个方向,否则另一个方向(任务队列?)如果不是。为什么不将 99% 的非相关工作分流到另一个流程,而无论您的最终设置可能用于更改排名,都只需要处理 100+1 个记录。

于 2012-05-25T16:08:54.370 回答