排行榜

1 前言

最早的排行榜,起源于在魔兽世界游戏的拍卖行,常规数据库mysql无法实现这一功能,但是redis可以解决。

redis的有序集合,可以实现这一功能。有序集合的底层是哈希(可以去重)和链表(指针,指向下一个元素的内存地址,方便插入)的结合。

  • 数组:某一数组的某一位置插入元祖,巨大成本错位,数组的缺陷(但是查询快),可以折半查找
  • 链表:链表查询慢,但是插入快,不能做折半查找,不知道长度,指针指向内存地址,无序,顺序查找(一个一个进行比对),for循环,跳表(123456789,查13579,跳跃性查找,弊端:把奇数节点拿到了,原节点不能删除,平白无故多了百分之五十的存储空间,以空间换时间)

为什么有序集合,确保唯一性,有序

2 redis相关

Microsoft Windows [版本 10.0.17763.1518]
(c) 2018 Microsoft Corporation。保留所有权利。

C:Users86156>redis-cli
127.0.0.1:6379> select 8
OK
127.0.0.1:6379[8]> zadd myscore 3 a			# 插入
(integer) 1
127.0.0.1:6379[8]> zadd myscore 4 b
(integer) 1
127.0.0.1:6379[8]> zincrby myscore 5 a		# 自增
"8"
127.0.0.1:6379[8]> zrange myscore 0 10		# 获取(django中是列表)
1) "b"
2) "a"
127.0.0.1:6379[8]> zscore myscore a
"8"
127.0.0.1:6379[8]> zscore myscore c
(nil)

3 实战代码

  • redis里面只需要加几行代码,并新写一个视图函数
# 排序所需代码
r = redis.Redis(db=9, decode_responses=True)
    m = r.zscore('money', user_id)
    # 如果有数据,要自增
    if m:
        r.zincrby(user_id, user_id, money)
    # 没有的话,直接插入即可
    r.zadd('money', {user_id: money})
    
from rest_framework.response import Response
from rest_framework.views import APIView

from userapp.models import UserModel


# 写一个新的视图函数
class ScoreView(APIView):
    def get(self, request):
        import redis
        r = redis.Redis(db=9, decode_responses=True)
        list = r.zrange('money', 0, 10)
        score_list = []
        for i in list[::-1]:
            dict = {}
            username = UserModel.objects.get(pk=i).username
            value = r.zscore('money', i)
            dict['username'] = username
            dict['money'] = value
            score_list.append(dict)
        return Response({'data':score_list})    

4 效果

原文地址:https://www.cnblogs.com/mapel1594184/p/14200733.html