我有一个游戏,每个玩家都有一个分数。我想有一个全球记分牌,玩家可以比较他们的分数,看看他们的位置和浏览记分牌。
不幸的是我无法找到一种有效的方法来编程:将当前玩家位置存储在记分板中意味着当玩家提高他的分数时我必须更新记分牌的大部分,而不是存储位置意味着我必须重新计算它每次我需要它(这也需要大量的计算)。
这个问题有更好的解决方案吗?或者上述解决方案之一是否“足够好”,可以在很多用户和大量更新中实际使用?
答案 0 :(得分:0)
ORDER BY
条款是为此而制定的,看起来并不那么慢。
答案 1 :(得分:0)
为了便于实施,我会考虑使用第二种解决方案。根据项目的大小,您应该能够使用ORDER_BY订购解决方案。
至于那是否“足够好”可能很大程度上取决于您的需求。在最糟糕的情况下,每次执行更新时对数据进行排序可能会很昂贵,但如果您发现ORDER_BY速度很慢,则可能需要考虑重写。
要问自己最好的问题是哪个操作会执行得更多?如果你很少写作和经常阅读,也许一种类型是个好主意。目前我建议使用ORDER_BY。
就实施该职位而言,有没有理由在您的数据模型中有这个并且不在输出上跟踪它?在输出行时,编写计数器似乎很容易,而且比将其存储在表中要少得多。
如果您想对请求执行此操作,似乎有一个使用this SO question存储过程的解决方案。
答案 2 :(得分:0)
我想我终于找到了一个解决方案,它不需要在每个分数更新时重新计算整个记分板。基本上,在伪SQL代码中:
max_rank = SELECT MIN(rank) FROM scoreboard WHERE score <= $new_score AND score >= $old_score
UPDATE scoreboard SET rank = rank + 1 WHERE score < $new_score AND score >= $old_score
UPDATE scoreboard SET rank = $max_rank, score = $new_score WHERE player = $player
排名仅针对旧分数和新分数之间的玩家进行更新(这仍然很多,但不如重新计算整个记分板的“天真”解决方案那么多.SQL数据库处理大部分工作:所有排名更新都在一个查询中完成。
除非有人发现问题,否则我会选择这个:)