Python Django:如何创建排行榜

Python Django:如何创建排行榜,python,sql,django,leaderboard,Python,Sql,Django,Leaderboard,假设我有大约1000000个用户。我想知道任何给定的用户处于什么位置,以及他周围的用户。用户可以在任何时候获得新的成就,如果他能看到自己的站更新,那就太好了 老实说,我想到的每一种方法在时间和/或记忆上都会非常昂贵。思想?到目前为止,我最接近的想法是离线订购用户并构建百分位桶,但这无法显示用户的确切位置 一些代码可以帮助您了解django人: class Alias(models.Model) : awards = models.ManyToManyField('Award', thro

假设我有大约1000000个用户。我想知道任何给定的用户处于什么位置,以及他周围的用户。用户可以在任何时候获得新的成就,如果他能看到自己的站更新,那就太好了

老实说,我想到的每一种方法在时间和/或记忆上都会非常昂贵。思想?到目前为止,我最接近的想法是离线订购用户并构建百分位桶,但这无法显示用户的确切位置

一些代码可以帮助您了解django人:

class Alias(models.Model) :
    awards = models.ManyToManyField('Award', through='Achiever')

    @property
    def points(self) :
        p = cache.get('alias_points_' + str(self.id))
        if p is not None : return p

        points = 0
        for a in self.achiever_set.all() :
            points += a.award.points * a.count

        cache.set('alias_points_' + str(self.id), points, 60 * 60) # 1 hour
        return points

class Award(MyBaseModel):
    owner_points = models.IntegerField(help_text="A non-normalized point value. Very subjective but try to be consistent. Should be proporional. 2x points = 2x effort (or skill)")
    true_points = models.FloatField(help_text="The true value of this award. Recalculated with a cron job. Based on number of people who won it", editable=False, null=True)

    @property
    def points(self) :
        if self.true_points :
            # blend true_points into real points over 30 days
            age = datetime.now() - self.created
            blend_days = 30
            if age > timedelta(days=blend_days) :
                age = timedelta(days=blend_days)
            num_days = 1.0 * age.days / blend_days
            r = self.true_points * num_days + self.owner_points * (1 - num_days)
            return int(r * 10) / 10.0

        else :
            return self.owner_points


class Achiever(MyBaseModel):
    award = models.ForeignKey(Award)
    alias = models.ForeignKey(Alias)
    count = models.IntegerField(default=1)

我认为反击可以通过要求用户达到最低排名门槛来解决这个问题——你只需要准确地对排名前10%的用户进行排序

如果你想对每个人排序,就认为你不需要对它们进行完美的排序:把它们分成2个重要的数字。有了100万用户,您可以实时更新排名前100位用户的排行榜,接下来的1000位用户最接近10位,然后将大众最接近1%或10%。你不会在一轮中从500000名跳到99名

将10个用户的上下文置于500000以上和以下是毫无意义的——由于指数分布,从一轮到另一轮的排序将令人难以置信地紧张

编辑:看一看。现在转到2500个(大约20%)中的一个。告诉有代表“157”的人,他们两边的10个人也有代表“157”有什么意义吗?如果你的代表上升或下降一个点,你会跳20个位置。更极端的是,目前底部的1056页(2538个页面中)或底部42%的用户与Rep1并列。你再得一分,你就跳了起来。这大约增加了37000个等级。告诉他们“如果你再得一分,你就可以打败370K人”可能很酷,但这与37k数字有多少重要数字有关系吗


在你还没有到达顶端之前,了解你的同龄人是没有价值的,因为除了顶端之外,其他任何地方都有大量的同龄人。

一百万并不多,我会先用简单的方法试试。如果要对points属性进行排序,则该属性必须是数据库列。然后,你可以只做一个点数大于有问题的人得到排名。为了让其他人接近问题中的人,你需要对得分较高的人进行查询,并按升序排序,将其限制为你想要的人数


最棘手的事情是计算保存时的点数。您需要使用当前时间作为奖金乘数。一个点现在需要变成一个数字,从现在起5天内小于1点。如果您的用户经常获得积分,您需要创建一个队列来处理负载。

有人请编辑此内容,以便更清楚地表达,我要睡觉了。我试图通过向用户展示高于他们的人来给他们一个目标,但不会太远以至于无法到达。分布底部的抖动将非常大,即使上升或下降1个点,也会使您在1米中下降或获得数千个位置。你应该衡量你的分数分布情况。