好友间实时更新相对排行榜
我一直在为我的应用程序开发一个排行榜功能,简单来说,就是根据用户的得分来排列他们的名次。目前我是在单独跟踪每个用户的得分。我想这个排行榜应该是相对的,而不是绝对的。也就是说,不是全站得分最高的前10名用户,而是用户朋友网络中的前10名。这种方式更好,因为每个人都有机会在自己的网络中成为第一名,而且对于那些喜欢这种竞争的人来说,也会有一种友好的竞争氛围。我已经在存储每个用户的得分,所以现在的挑战是如何高效地实时计算这个得分的排名。我使用的是Google App Engine,这样有一些好处和限制(比如,IN [array] 查询会对数组中的每个元素执行子查询,并且每个语句最多只能处理30个元素)
举个例子:
1. Jack 100
2. John 50
我想出了几种方法,但似乎都不够高效,所以我觉得这个社区可能能想出更优雅的解决方案。我觉得任何解决方案可能都需要用到定时任务(cron),我会存储每天的排名和列表顺序,以优化读取操作,但如果有更轻量级和实时的方案就太好了。
- 拉取全站所有用户按得分排序的列表。 从这个列表中为每个用户挑选他们的朋友,并创建新的排名。 存储排名和列表顺序。 每天更新。 缺点 - 如果用户很多,这个过程会非常耗时。
2a. 为每个用户挑选他们的朋友,然后为每个朋友获取得分。 对这个列表进行排序。 存储排名和列表顺序。 每天更新。 记录每个用户的最后位置,以便在下次更新时可以利用已有的列表进行重新排序,从而提高效率(可能节省排序时间)。
2b. 和上面的方法一样,只不过只计算在过去一天内查看过的用户的排名和列表顺序。 缺点 - 排名只会在第二个查看该资料的人之后更新。
2 个回答
有一个Python库可以用来存储排名信息:
如果写入操作(更新数据)相比读取操作(获取数据)非常少见(这是大多数键值存储的一个关键假设,不仅仅是这些情况;-),那么在需要更新分数(写入)时,你可能更愿意花点时间,而不是在获取相对排行榜(读取)时。具体来说,当用户的分数发生变化时,可以为他们的每个朋友排队任务,更新他们的“相对排行榜”,并将这些排行榜作为列表属性(这样可以保持顺序!-)进行适当的排序(没错,这就是所谓的反规范化——为了更好地利用键值存储,通常需要适当地重复信息!-)。
当然,当朋友关系(用户之间的连接)消失或出现时,你也会更新相对排行榜,但我想这些情况应该比分数更新更少见;-)。
如果写入操作比较频繁,因为你不需要每秒钟都精确的信息(也就是说,这不是财务或会计方面的内容;-),你仍然有很多可行的方法可以尝试。
例如,较大的分数变化(比较少见)可能会触发相对排行榜的重新计算,而较小的变化(更频繁)则可以暂时存储起来,只有在“有空的时候”才应用。没有具体的数字很难更详细地说明,比如各种规模的更新频率、典型的网络好友群体大小等等。我知道,和其他人一样,你希望有一个完美的方法,适用于所有不同的规模和频率……但你就是找不到这样的方法!-)