【发布时间】:2015-11-09 03:03:05
【问题描述】:
我有一个 Django 模型:
from django.db import models
class Player(models.Model):
name = models.CharField(max_length=254, null=True, blank=True,)
score = models.IntegerField()
A = Player.create(name="A", score=99)
B = Player.create(name="B", score=66)
C = Player.create(name="C", score=66)
D = Player.create(name="D", score=55)
E = Player.create(name="E", score=44)
我想保持我所有球员的得分排名。如果玩家得分相同,他们将获得相同的排名。所以在这种情况下,排名将如下所示:
Name Score Rank
A 99 1
B 66 2
C 66 2
D 55 4
E 44 5
我想将此排名存储在数据库中,这样我就不必经常执行昂贵的排序查询。我需要高效地执行以下所有操作:
- 给定一个玩家,查找他们的排名
- 给定一个排名,找出哪些玩家拥有该排名
- 给定一个玩家,将其插入此排名
- 给定一个玩家,将其从该排名中删除
- 给定一名球员和一个分数,更新他们在此排名中的位置
我需要从这个列表中插入和删除玩家。每当我做#3、#4 或#5 时,我都需要相应地更新其他玩家的排名,以保持排名的完整性。
在 Django 中最有效的方法是什么?我如何构建我的模型,这样它才能有效地工作并且我的数据库操作将最小化?请告诉我任何新模型应该是什么样子。
【问题讨论】:
-
“每当我做#3、#4或#5时,我都需要更新其他玩家的排名……” - 这比计算更昂贵即时排名。如果每次插入/删除玩家时都必须更新排名,那么在数据库中存储排名似乎不是一个好主意。
-
Xyres,我不能只使用数据库子句“order by”轻松计算这些排名,因为如您所见,我的排名函数有点复杂(即:可能有两个玩家排名第一)。此外,插入/删除播放器将比查找少得多。
-
您不仅限于使用
order_by。您可以编写自定义代码来计算排名。我写了一个即时计算排名的算法。请参阅下面的答案。 -
查看 Redis SortedSets,它们非常适合您的问题:“Sorted Set 的每个成员都与 score 相关联,用于将有序集合从最小到最大排序. 虽然成员是独一无二的,但分数可能会重复。” redis.io/topics/data-types
标签: python mysql django database sorting