共计 3294 个字符,预计需要花费 9 分钟才能阅读完成。
目前啊,公司有些动荡,程序员?? 真是不容易呀。自己趁着空余的时间,将原来看过的书和知识点再捋一遍。
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,已经存在返回 0smembers set-key
sismember set-key item
已经存在返回 1,不存在返回 0srem 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 对文章进行投票
- 业务分析
- 可以对文章进行点赞
- 文章评分:得票数 * 常量 + 文章发布时间
- 每人每篇只能投一次,只能投一周
- 数据构建设计
- hash 文章信息(标题、网址、发布用户、发布时间、投票数)
- zset 文章发布时间(文章 ID、发布时间)- 可以通过发布时间排序
- zset 文章评分(文章 ID、评分)- 可以通过评分排序
- set 文章已投用户列表(key- 文章 ID、value- 已投用户 ID)- 一周后就可删除
- 实现逻辑
- 当用户尝试对一篇文章投票,先去文章发布时间的 zset 中 (zscore 命令) 检查文章是否超过一周
- 如果文章仍然可以投票,zadd 将用户添加到文章已投用户列表 set 中
- 如果添加成功,则表示该用户第一次对该文章投票,并 (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 发布文章
- 实现逻辑
- 首先创建一个文章 ID,可以通过计数器(INCR 命令)
- 将文章作者 ID 添加 (SADD 命令) 到文章已投用户列表,本人默认已经投了自己的文章
- 为文章已投用户列表的 set 设置 (EXPIRE 命令) 过期时间,1 周后自动删除
- 存储 (HMSET) 文章相关信息
- 将初始评分和发布时间分别添加 (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 获取文章(评分最高的文章、最新发布的文章)
- 实现逻辑
- 先使用 ZREVRANGE(倒序范围取值)在 zset 中取出多个文章 ID
- 然后在 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 对文章进行分组(分类,标签等类似功能), 并取出分组中评分最高或时间最新文章
- 实现逻辑
- 分组可使用集合 set
- 将分组集合 set、评分有序集合 zset(或者时间的有序集合 zset),进行交集 (ZINTERSTORE 命令) 计算,存储到一个有序集合
- 然后从有序集合中获取排序的文章信息,为了减少 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)