redis系列整体栏目
内容 | 链接地址 |
---|---|
【一】redis基本数据类型和使用场景 | https://zhenghuisheng.blog.csdn.net/article/details/142406325 |
redis基本数据类型和使用场景
- 一,redis基本数据类型和使用场景
- 1,String数据类型
- 2,Hash数据类型
- 3,List数据类型
- 4,Set数据类型
- 4.1,抽奖设计
- 4.2,点赞收藏设计
- 4.3,社交系统实现
- 5,Zset数据类型
一,redis基本数据类型和使用场景
在实际开发中,经常会用到一些缓存中间件,如redis,但是redis除了做缓存之外,还能做很多事情,本篇文章主要来讲解一下redis的基础数据类型。
我这边选用的是redis5.0的版本,然后通过docker安装的,因此直接进入docker容器内部,执行启动redis命令
//展示docker正在运行的容器,获取容器id
docker ps
//进入docker容器内部
docker exec -it d4fc743db4ad /bin/bash
//启动redis
redis-cli
在redis中,主要有5中数据类型:String数据类型、Hsah数据类型、list数据类型、set数据类型、zset数据类型
1,String数据类型
String类型在redis中的使用场景相对比较广泛,采用普通的 key-value 键值对的方式实现,一般更加的倾向于做缓存使用,如直接设置和获取某个值
set zhenghuisheng 18
get zhenghuisheng
当然在实际开发中,一般都会设置某个前缀,别上面的是设置年龄,那么就会在前面拼接一个年龄前缀
set age:zhenghuisheng 18
同时也可能直接会存某个被序列化的json对象,直接作为字符串存储在redis中,如在小商城中,可以直接将用户下单的订单信息存储在redis中,通过前缀+订单id作为key,然后被序列化的对象作为value
set order:12345 "{userId:1,money:200,productId:1}"
除了作缓存之外,String类型还能做简单的分布式锁,由于内部执行命令的线程为单线程,因此可以直接通过setnx命令来执行一把分布式锁
//设置一把分布式锁
setnx stock:lock true
//释放分布式锁
del stock:lock true
如下图所示,当第一个线程拿到这把分布式锁后,后面的线程会抢不到,直到把这把锁释放,其他线程才能拿到
String类型也可以做session会话,比如在实际开发中,直接将用户的token存入到redis中
set session:userid:12345 "session_data" EX 3600 # 1小时过期
也可以做限流操作,如在实际开发中,结合aop和自定义注解统计每个接口1分钟内外部调用的次数,当超过1000次时则对这个ip进行限流的操作
incrby api:rate_limit:ip:123.45.67.89 1000
expire api:rate_limit:ip:123.45.67.89 60 # 60秒过期
最后就是这个自增,比如统计文章的浏览数,某个街道通过的车辆数等等,那么就可以结合自增来实现
incr zhenghuisheng
总结:在实际开发中,String类型可以用作简单的分布式锁、计数器、session会话、限流等
2,Hash数据类型
hash有点类似于hash表,更加倾向于存储对象类型的数据,比如在实际开发中存对象可能会用序列化的String类型存,但是其实也是可以选择使用hash的数据类型存储。
HSET user:1001 name "zhenghuisheng" age 25 email "alice@example.com"
HGETALL user:1001 # 获取用户的所有信息
还有就是存一些商品信息,价格,描述等
HSET product:2001 name "小米8" price 1200 stock 30 description "米8"
HGET product:2001 price # 获取商品的价格
相对于String类型,hash类型存储这些对象信息是更加的节省空间,而且对数据管理更加灵活方便。
hash类型也存在缺陷,就是存储的对象不能太大,否则会造成 大key 的问题,造成redis阻塞
3,List数据类型
list底层采用的是双向链表,允许数据从双端进行插入或者删除,list的常用命令如下
LPUSH
/ RPUSH
:在列表左/右侧插入元素。
LPOP
/ RPOP
:从列表左/右侧弹出元素。
LRANGE
:获取列表中指定范围内的元素。
LLEN
:获取列表长度。
LREM
:移除列表中指定的元素
结合双向链表的特性,可以实现很多数据结构,如通过list设计一个栈、队列、或者设计一个阻塞队列
设计一个栈的思路如,栈的本质是先进后出,因此可以通过左边进左边取的的设计思路结合
lpush + lpop
设计一个Queue队列的思路如下,队列的本质是先进先出,那么数据就从左边取,右边进的原则
lpop + rpush
设计一个阻塞队列的思路如下,就是在数据出的时候,阻塞一下,通过blpop实现
blpop + rpush
在实际开发中,如拉取订阅的消息时,可以采用这种list方式拉取数据,通过时间线进行排序,最近的消息排在前面,如微博那边就是这样子设计的,直接通过lpush + lpop的方式实现
LRANGE timeline:user_1001 0 9 # 获取最近的 10 条动态
还有在一些经常需要分页的场景中,如某类商品的详情页需要分页查看
LPUSH products_page_1 "product_1001" "product_1002"
LRANGE products_page_1 0 9 # 获取第 1 页的 10 条产品数据
还有查看一些日志,也可以通过这种队列的方式实现,如查看最近的100条日志
LRANGE error_logs 0 9 # 获取最新的 10 条日志
4,Set数据类型
Redis 中的 Set
数据类型是一个无序集合,集合中的元素是唯一的 ,因此首先是适合需要记录唯一元素。如统计某个网站一天有多少人浏览,这时就需要通过用户id进行去重操作,那么就可以寻找set这种数据结构类型
4.1,抽奖设计
set还可以设计一个抽奖的功能,通过里面的随机值来实现,批量插入10条数据
SADD lottery:2024 1 2 3 4 5 6 7 8 9 10
然后查看所有参与了抽奖的用户,此时10个用户已经就绪
SMEMBERS lottery:2024
随后抽奖两次,每次抽3个人,可以发现每次抽到的人都不一样
SRANDMEMBER lottery:2024 3
当然有时候业务也可能不一样,就是说第一次得奖者不能参与第二次抽奖,那么需要使用这个 SPOP 命令
SPOP lottery:2024 3
4.2,点赞收藏设计
点赞系统设计:
- 用户点赞: 使用 Redis
Set
来存储某个内容的点赞用户,每个内容对应一个Set
,用户的 ID 是集合中的元素,保证每个用户只能对某个内容点赞一次。 - 取消点赞: 用户取消点赞时,从
Set
中移除用户 ID。 - 统计点赞数: 通过
SCARD
命令统计集合的元素数量,即为点赞数。 - 查询某个用户是否点赞过: 使用
SISMEMBER
判断用户是否在Set
中。 - 获取所有点赞的用户列表: 使用
SMEMBERS
获取点赞用户 ID 列表。
关键 Redis 命令:
SADD
: 向集合中添加元素(点赞)。SREM
: 从集合中移除元素(取消点赞)。SCARD
: 获取集合的元素数量(点赞数)。SISMEMBER
: 判断用户是否在集合中(查询是否已点赞)。SMEMBERS
: 获取集合中的所有元素(点赞用户列表)。
执行命令如下
SADD user:star:2024 1 2 3 //添加3个点赞用户
SREM user:star:2024 1 //用户1取消点赞
scard user:star:2024 //统计点赞数
sismember user:star:2024 1 //查询某个用户是否点赞
smembers user:star:2024 //获取所有的点赞列表
4.3,社交系统实现
使用 Redis 的 Set
数据类型可以有效地设计一个社交网络的好友关系系统。通过 Set
,我们可以轻松管理用户的好友列表,实现好友的添加、删除、查询和好友推荐等功能 。一般的社交系统,都能通过这种关注模型实现
好友关系设计:
- 添加好友:使用
Set
存储每个用户的好友列表,好友 ID 是集合中的元素。 - 删除好友:使用
SREM
从集合中移除好友 ID。 - 查看好友列表:使用
SMEMBERS
获取用户的所有好友 ID。 - 检查是否是好友:使用
SISMEMBER
判断某个用户是否在另一个用户的好友列表中。 - 推荐好友:可以使用集合的交集和并集来推荐可能的好友。
关键 Redis 命令:
SADD
: 向集合中添加元素(添加好友)。SREM
: 从集合中移除元素(删除好友)。SMEMBERS
: 获取集合的所有元素(查看好友列表)。SISMEMBER
: 检查元素是否在集合中(是否是好友)。SINTER
: 获取多个集合的交集(推荐好友)。SUNION
: 获取多个集合的并集(找出所有好友)。
执行命令如下
SADD user:1:friends 2 3 //用户1添加用户2和3为好友
SADD user:2:friends 1 4 //用户2添加用户1和4为好友
SADD user:3:friends 1 //用户3添加用户1为好友SREM user:1:friends 2 //用户1删除用户2
SMEMBERS user:1:friends //查看用户1的全部好友
SISMEMBER user:3:friends 1 //检查用户1是不是用户3的好友SINTER user:1:friends user:3:friends 推荐用户3的好友,但用户1不是好友
5,Zset数据类型
zset的使用命令和set差不多,就是要在前面加一个z。与set不同的是,zset内部是进行了排序的
其使用的基本实现如下,如简单的实现一个分数的排行榜
首先添加用户及其得分
# 1. 添加用户及其得分
ZADD leaderboard 100 "user1"
ZADD leaderboard 200 "user2"
ZADD leaderboard 150 "user3"
然后更新用户1的分数
# 2. 更新用户1的分数
ZADD leaderboard 250 "user1"
获取得分最高的前 3 名用户
ZRANGE leaderboard 0 2 WITHSCORES
# 返回:["user1", "250", "user2", "200", "user3", "150"]
查看 user1 的分数
ZSCORE leaderboard "user1"
# 返回:250
删除 user2
ZREM leaderboard "user2"
获取第 2 到第 4 名的用户(此时可能没有第 3 名和第 4 名)
ZRANGE leaderboard 1 3 WITHSCORES
# 返回:["user3", "150"](用户2已被删除)
获取得分最高的前 3 名用户(从高到低)
ZREVRANGE leaderboard 0 2 WITHSCORES
# 返回:["user1", "250", "user3", "150"]