redis系列之--数据结构设计

redis系列之–数据结构设计


redis数据结构和常用操作

  • String -->语法格式:key value 可理解为{key:value}

    • 记录字符串/整数/浮点数
    • 命令
      • set 添加/修改数据
      • get 获取数据
      • mset 添加多个数据
      • mget 获取多个数据
      • incr 计数加1
      • decr 计数减1
      • incrby 计数加n
  • 键命令

    • 适用于所有的类型
    • 命令
      • del 删除数据
      • exists 判断数据是否存在
      • expire 设置过期时间
      • ttl 获取剩余时间
      • keys 查询满足条件的键
  • hash -->语法格式:key field1 value1 field2 value2 … 可理解为可以key:{ field1: value1, field2 :value2 …}

    • 类似字典的结构
    • 命令
      • hset 添加字段
      • hget 获取字段
      • hmset 添加多个字段
      • hmget 获取多个字段
      • hdel 删除字段
  • list -->语法格式:key value1 [value2, …] 可理解为key:[value1, value2, …]

    • 是一个双向链表
    • 命令
      • lpush 从左侧追加元素
      • lrange 从左侧遍历元素
      • rpush 从右侧追加元素
      • lset 从左侧修改元素
      • lpop 从左侧删除元素
      • rpop 从右侧删除元素
      • ltrim 裁切列表
  • zset -->语法格式:key score member [score member …] 可理解为key:{member1:score1, member2:score2, …}

    • 有序集合, 按照分数(score)进行排序
    • 命令
      • zadd 添加/修改元素
      • zrange 遍历元素(按分数从小到大)
      • zrevrange 反向遍历元素(从大到小)
      • zrangebyscore 遍历指定分数范围的元素
      • zscore 查询元素的分数
      • zrem 删除元素
      • zincrby 元素的分数计数加n
  • set -->语法格式:key member [member … 可理解为key:[member1, member2, …]

    • 无序集合 无序+去重

    • 命令

      • sadd 添加元素
      • smembers 遍历元素
      • sismember 判断是否包含
      • srem 删除元素

数据结构设计案例

新闻页面
  • 记录某条新闻的详细数据 hash
  • 记录新闻id string
  • 记录最新的100条新闻 list
  • 记录所有的新闻及点赞数 zset
  • 记录对某条新闻点赞的用户 set
from redis import Redis

# 创建redis客户端
# redis-py 3.0 之前需要使用 StrictRedis() 来建立数据库连接对象
# redis_client = StrictRedis(host='127.0.0.1', port=6379, db=0, decode_responses=True)
redis_client = Redis(decode_responses=True)


def release_news(title, content):
    """
    发布新闻
    :param title: 新闻标题
    :param content: 新闻内容
    """
    # 生成新闻id
    news_id = redis_client.incr("news_id")  # incr返回的是当前的计数, 类型为整型
    news_key = "news:" + str(news_id)
    # 记录新闻数据到hash中
    redis_client.hmset(news_key, {
        "title": title,
        "content": content
    })
    # 设置缓存(过期)时间  7天
    redis_client.expire(news_key, 7 * 86400)
    # 将新闻保存到最新发布列表中
    redis_client.lpush("latest_news_list", news_key)
    # 裁切发布列表  只保留100条新闻
    redis_client.ltrim("latest_news_list", 0, 99)
    # 将新闻保存到新闻有序集合中
    redis_client.zadd("news_zset", {news_key: 0})


def show_latest_news():
    """获取最新的30条新闻"""
    return redis_client.lrange("latest_news_list", 0, 29)


def show_fav_news():
    """获取30条最受欢迎(点赞最多)的新闻"""
    return redis_client.zrange("news_zset", 0, 29, desc=True)  # 点赞数 多 到 少 取前30条


def news_like(news_key, user_key):
    """对新闻点赞"""
    news_id = news_key.split(":")[-1]
    news_like_key = "news_like:" + news_id

    if redis_client.sadd(news_like_key, user_key):  # 判断该用户是否对新闻点过赞, 没有点过赞才点赞数加1
        # 让zset中的新闻的分数加1
        redis_client.zincrby("news_zset", 1, news_key)


def show_news_detail(news_key):
    """显示新闻详情"""
    keys = ['title', "content"]

    if redis_client.exists(news_key):  # 判断redis是否有该新闻的缓存(判断键是否存在)
        vals = redis_client.hmget(news_key, keys)
        # 字典推导式
        return {keys[index]: vals[index] for index in range(2)}

    else:
        # TODO 从mysql中取出新闻数据
        sql_data = {"title": "快下课", "content": "好的"}

        # 将数据保存到redis中缓存
        redis_client.hmset(news_key, {
            "title": sql_data["title"],
            "content": sql_data["content"]
        })
        # 设置缓存(过期)时间  7天
        redis_client.expire(news_key, 7 * 86400)

        return sql_data


if __name__ == '__main__':
    # 发布新闻
    # release_news("你好", "叔叔不约")
    # release_news("吃了吗", "没吃")
    # release_news("放学别走", "老地方见")

    # 显示最新发布列表
    news_list = show_latest_news()
    # # print(news_list)
    one_news_key = news_list[2]
    # # 点赞
    # news_like(one_news_key, "user:1")
    # news_like(one_news_key, "user:1")  # 只会点赞成功一次
    # # 显示点赞列表
    # news_like_list = show_fav_news()
    # print(news_like_list)

    # 获取新闻详情
    news_detail = show_news_detail("news:7")
    print(news_detail)


你可能感兴趣的:(web开发,python,网络编程,数据库)