redis排行榜
需求
如果一个需求是类似王者荣耀的巅峰赛排行榜, 同分的情况下我们如果想让先到同分的那一个排前面怎么办.
解决方案
我是将获取第二年的一月的时间戳乘于1000000, 然后-去当前时间戳乘于1000000给同分加上小数, 这样就解决了同分的问题
上代码:
import math
import time
from redis import StrictRedis
from retry import retry
sort_manager = StrictRedis(host="127.0.0.1", port=6379, db=0, password="",
decode_responses=True)
@retry(tries=10, delay=0.01)
def add_score_redis(control_key: str, user_uuid: str, score: float):
"""
添加分数排行榜
:param control_key: 排行榜的key
:param score: 分数
:param user_uuid: 用户的uuid
:return: None
"""
old_score = sort_manager.zscore(control_key, user_uuid)
if old_score:
if math.floor(old_score) < math.floor(score):
sort_manager.zadd(control_key, {user_uuid: score}) # 更新分数
return
return
if not old_score:
sort_manager.zadd(control_key, {user_uuid: score}) # 添加分数
return
def get_score_list(control_key: str, start: int = 0, end: int = -1, show_scores: bool = False) -> list:
return sort_manager.zrevrange(control_key, start, end, withscores=show_scores)
def get_user_ranking(control_key: str, user_uuid: str) -> list:
"""
获取自己的排名
:param control_key:
:param user_uuid:
:return: [排名, 分数]
"""
return [sort_manager.zrevrank(control_key, user_uuid), sort_manager.zscore(control_key, user_uuid)]
def get_float_score(end_time: int, score: int) -> float:
"""
返回浮点数的分数
:param end_time: 结束时间的排行榜
:param score: int 分数
:return: float 分数
"""
end_float_str = "0." + str(end_time * 1000000 - int(time.time() * 1000000))
return float(score) + float(end_float_str)
if __name__ == '__main__':
control_key = "socre_ranking"
SOCRE_END_TIME = 1672502400 # 2022年排行榜
# 两个同分, 排序肯定是按照先入的排前面
add_score_redis(control_key, "1", get_float_score(SOCRE_END_TIME, 100))
add_score_redis(control_key, "2", get_float_score(SOCRE_END_TIME, 100))
add_score_redis(control_key, "3", get_float_score(SOCRE_END_TIME, 101))
add_score_redis(control_key, "4", get_float_score(SOCRE_END_TIME, 100))
print("-----获取个人排名-----这里返回的第一名是[0,分数] 所以你的索引要加一")
print(get_user_ranking(control_key, "2"))
print(get_user_ranking(control_key, "4"))
print("-----获取一段范围的排名------")
print(get_score_list(control_key, 0, 1, True)) # 这个已经是排好序了的 后面自己用math.floor向下去就OK
print(math.floor(100.99999999999999))
版权声明:本文为qq_41929657原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。