小王
文章8
标签3
分类5
redis实现排行榜

redis实现排行榜

redis排行榜

为什么使用Redis实现排行榜?

  1. Redis作为一款缓存数据库,性能优异,使用Redis可以提升服务存取数据的性能。
  2. Redis的zset(有序集合)数据结构,天然具备作为排行榜的优势。

怎么使用Redis实现排行榜?

  1. 使用Redis的zset数据结构,其中key为固定值,value为排行榜名称(唯一id),score为排行分数(排序点击数)。
  2. 我们记录点击数,每点击一次,点击次数越多在排行榜中所在的排名越高。
  3. Redis的zset数据结构,使用的是从大到小的排序方式,所以我们使用负数来作为排名分数,每点击一次,排行榜的分数+1。
# 写入
r.zincrby('my_sortset',1, 3)  # (key,排序点击数,唯一id) 在里面写入了一次id为3的一次点击

# 排序
myset = r.zrevrange('my_sortset',0,-1,withscores=True)[:num]  # (key,开始,结束,针对点击数排序) 0从开-1最后就是全部 [:num]是切片操作

# 和mysql联动
course = Course.objects.in_bulk([int(item[0]) for item in myset])

zincrbyzrevrangein_bulk

demo

import redis
import json
from .models import Goods
from .ser import GoodsSer
from django.shortcuts import HttpResponse


r = redis.Redis(host='localhost', port=6379)

# 课程点击数统计
def click(request):
    cid = request.GET.get('cid')
    # 使用redis有序集合来记录
    r.zincrby('goods_click', 1, int(cid))

    res = {}
    res['code'] = 200
    res['message'] = '页面访问成功'
    return HttpResponse(json.dumps(res, ensure_ascii=False), content_type='application/json')

# 获取排行榜前n位的数据
def get_top_n_users(num):
    # 获取所有有序集合元素,进行切片操作
    goods_click = r.zrevrange('goods_click', 0, -1, withscores=True)[:num]

    '''
    print(goods_click)
    》 [(b'3', 4.0), (b'1', 3.0), (b'2', 2.0)]
    '''

    # 和mysql联动
    goods = Goods.objects.in_bulk([int(item[0]) for item in goods_click])

    '''
    print([int(item[0]) for item in goods_click])
    》 [3,1,2]

    print(goods)
    》 {1: <Goods: 辣条>, 2: <Goods: 酸奶>, 3: <Goods: 雪糕>}
    '''

    # 将点击数和mysql结果结合
    res = []
    # 遍历
    for item in goods_click:
        try:
            res.append({int(item[1]): goods[int(item[0])]})
        except Exception as e:
            print(str(e))
            pass
    '''
    print(item)
    》 (b'3', 4.0)

    print(item[1])
    》 4.0

    print(item[0])
    》 b'3'
    '''
    return res

# 获取排行榜真实数据
def get_goods_list(request):
    # 调用数据
    get_goods = get_top_n_users(3)

    '''
    print(get_goods)
    》 [{4: <Goods: 雪糕>}, {3: <Goods: 辣条>}, {2: <Goods: 酸奶>}]
    '''

    res = []
    # 拼装json
    for dic in get_goods:
        for k, v in dic.items():
            # 序列化
            data = GoodsSer(v).data
            # 增加点击数字段
            data['click_number'] = k
            res.append(data)

    return HttpResponse(json.dumps(res, ensure_ascii=False), content_type="application/json")

效果

[
{"id": 3, "name": "雪糕", "price": 30, "click_number": 4},
{"id": 1, "name": "辣条", "price": 10, "click_number": 3},
{"id": 2, "name": "酸奶", "price": 20, "click_number": 2}
]
本文作者:小王
本文链接:https://wswle.cn/20201008.html
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可
×