1

目前啊,公司有些动荡,程序员?‍?真是不容易呀。自己趁着空余的时间,将原来看过的书和知识点再捋一遍。

ps:
纯手打,希望大家多多关注和点赞,后续陆续更新,希望大家一起进步!
图片使用的是processOn画的,有兴趣的小伙伴可以去试一下
如果同学需要电子书,可以评论区留言
吐槽processon,非会员文件最多9个,坑!

第一部分 入门

第一章 初识 redis

1.1 Redis简介
  • Redis 概念
Redis是一个速度很快的非关系型数据库,可以存储key-value之间的映射,可以将存储在内存中的键值对数据持久化到硬盘,可以使用复制特性来扩展读性能,可以使用客户端分片来扩展写性能
  • Redis与其他数据库对比
数据库名称 类型 数据存储 查询类型 附件功能
Redis 使用内存存储(in-memory)非关系型数据库 字符串、列表、集合、散列、有序集合 每种数据类型都有自己的专属命令,另外还有批量操作和不完成的事务支持 发布订阅、主从复制、持久化、脚本
memcached 使用内存存储的键值缓存 键值对之间的映射 创建、读取、更新、删除等命令 为提升性能而设的多线程服务器
MySQL 关系型数据库 数据库-表-行 结构 CURD相关函数 支持ACID特性、主从复制、主主复制
postgresql 关系型数据库 同上 同上 同上
MongoDB 使用硬盘存储(on-disk)的非关系文档存储 数据库-表-BSON文档 结构 创建、读取、更新、删除等命令 支持map-reduce操作、主从复制、分片、空间索引
  • 附加特性
  • RDB 和AOF 两种持久化方式
  • 支持主从复制
①执行复制的从服务器
1.2 Redis数据结构

  • 字符串 string
set hello world
get hello
del hello
  • 列表 list
rpush list-key item
lpush list-key item2
lrange list-key 0 -1
lindex list-key 1
lpop list-key
rpop list-key
  • 集合 set
列表可以存储多个相同字符串,集合存储的字符串各不相同
sadd set-key item 添加成功返回1,已经存在返回0
smembers set-key
sismember set-key item 已经存在返回1,不存在返回0
srem set-key item
  • 散列 hash
可以将hash看做关系型数据库的
hset hash-key sub-key1 value1
hgetall hash-key
hdel hash-key sub-key1
hget hash-key sub-key1
  • 有序集合 zset
  • 有序集合和散列,都可以存储键值对
  • 有序集合中,键:成员,值:分值,分值必须为浮点数
  • Redis中唯一一个,既可以根据成员访问元素,又可以根据分值以及分值的排列顺序访问元素的结构
    zadd zset-key 123 member1
    zrange zset-key 0 -1 withscores
    zrangeby zset-key 0 800 withscores 根据分值的范围查找
    zrem zset-key member1
1.3 Redis案列分析(类stackoverflow)
1.3.1 对文章进行投票
  • 业务分析
  1. 可以对文章进行点赞
  2. 文章评分:得票数 * 常量 + 文章发布时间
  3. 每人每篇只能投一次,只能投一周
  • 数据构建设计
  1. hash 文章信息(标题、网址、发布用户、发布时间、投票数)
  2. zset 文章发布时间(文章ID、发布时间)-可以通过发布时间排序
  3. zset 文章评分(文章ID、评分)-可以通过评分排序
  4. set 文章已投用户列表(key-文章ID、value-已投用户ID)-一周后就可删除
  • 实现逻辑
  1. 当用户尝试对一篇文章投票,先去文章发布时间的zset中(zscore命令)检查文章是否超过一周
  2. 如果文章仍然可以投票,zadd将用户添加到文章已投用户列表set中
  3. 如果添加成功,则表示该用户第一次对该文章投票,并(zincrby命令)为文章评分zset添加400(设置的常量),并(hincrby命令)为文章信息hash中投票数+1
  • 代码展示 python
’‘’
    这里应该使用Redis事务,后续章节再添加进来
‘’‘
ONE_WEEK_IN_SECONDS = 7 * 86400
VOTE_SCORE  = 400

def article_vote(conn,uer,article):
    cutoff = time.time() - ONE_WEEK_IN_SECONDS
    if conn.zscore('time:'+ article)< cutoff
        return
    # -1的好处是无论前面添加了栏目,ID的索引-1    
    article_id = article.partition(':')[-1]
    if conn.sadd('voted:' + article_id,user)
        conn.zincrby('score:',article,VOTE_SCORE)
        conn.hincrby(article,'votes',1)
1.3.2 发布文章
  • 实现逻辑
  1. 首先创建一个文章ID,可以通过计数器(INCR命令)
  2. 将文章作者ID添加(SADD命令)到文章已投用户列表,本人默认已经投了自己的文章
  3. 为文章已投用户列表的set设置(EXPIRE命令)过期时间,1周后自动删除
  4. 存储(HMSET)文章相关信息
  5. 将初始评分和发布时间分别添加(ZADD)到对应的有序集合中
  • 代码展示 Python
def post_article(conn,user,title,link):
    article_id = str(conn.incr('article:'))
    voted = 'voted:' + article_id
    conn.sadd(voted,user)
    conn.expire(voted,ONE_WEEK_IN_SECONDS)
    
    now = time.time()
    article = 'article:' + article_id
    conn.hmset(article,{
        'title':title,
        'link':link,
        'poster':user,
        'time':now,
        'votes':1  
    })
    conn.zadd('time:',article,now)
    conn.zadd('score:',article,now + VOTE_SCORE)
1.3.3 获取文章(评分最高的文章、最新发布的文章)
  • 实现逻辑
  1. 先使用ZREVRANGE(倒序范围取值)在zset中取出多个文章ID
  2. 然后在hash中对每篇文章ID执行HGETALL取出文章详细信息
  • 代码实现 Python
ARTICLES_PER_PAGE = 25
def get_articles(conn,page,order='score:'):
    start = (page-1) * ARTICLES_PER_PAGE
    end  = start + ARTICLES_PER_PAGE -1
    ids  = conn.zrevrange(order,start,end)
    articles = []
    for id in ids:
        article_data = conn.hgetall(id)
        # 给源数据添加ID
        article_data['id'] = id 
        articles.append(article_data)
    return articles
1.3.3 对文章进行分组(分类,标签等类似功能),并取出分组中评分最高或时间最新文章
  • 实现逻辑
  1. 分组可使用集合set
  2. 将分组集合set、评分有序集合zset(或者时间的有序集合zset),进行交集(ZINTERSTORE命令)计算,存储到一个有序集合
  3. 然后从有序集合中获取排序的文章信息,为了减少Redis计算量,将交集结果缓存60秒
  • 代码实现 Python
def get_group_articles(conn,group,page,order='score:'):
    #交集的key
    key = order + group 
    if not conn.exists(key):
        conn.zinterstore(key,['group:'+group,order],aggregate='max')
        conn.expire(key,60)
    #调用原有方法获取文章排序    
    return get_articles(conn,page,key)    

苏香门第
22 声望3 粉丝

个人网站:[链接]