文章目录
- 前言
- 一、Redis的数据结构?
- 二、string常用方法和使用场景
- 1.常用方法介绍
- 2.string使用场景介绍
- 三、hash常用方法和使用场景
- 1.hash常用方法
- 2.hash使用场景
- 四、list常用方法和使用场景
- 1.list常用方法
- 2.list使用场景
- 五、set常用方法和使用场景
- 1.set常用方法
- 2.set使用场景
- 六、zset常用方法和使用场景
- 1.zset常用方法
- 2.zset使用场景
- 六、总结
前言
今天分享Redis的五种数据结构以及他们在实战中的使用场景
一、Redis的数据结构?
我们都知道Redis是现在大型系统中必不可少的中间件工具。他可以支持高并发的场景,也可以支持分布式锁。这都与他的设计架构和底层的数据结构有离不开的关系。Redis它是一个K,V结构的非关系型数据库。共有5种数据类型。分别是string、hash、list、set、zset。我们所说的数据类型只是Value不同,key都是string类型的。这里我画了一张图。

二、string常用方法和使用场景
1.常用方法介绍
#字符串常用操作
set key value //存储字符串的键值对
mset key value [key value …] //批量存储字符串的键值对
setnx key value //存储一个不存在的字符串的键值对
get key //根据key获取一个value
mget key [key …] //批量获取value
del key [key …] //删除键
expire key seconds //设置一个key的过期时间
#原子加减
incr key //将key中存储的数字值加1操作
decr key //J将key中存储的数字值减1操作
incrby key increment //将key中所存储的值加上increment
decrby key decrement //将key中所存储的值减上decrement简单演示一下:


2.string使用场景介绍
- 普通的单值缓存(一般存储用户的token)
set key value
get key

- 对象缓存(储存用户信息)
set user:110:info value(json数据格式)
mset user:110:name fafa user:110:age 18 - 分布式锁
setnx product:10010 true
del product:10010
set product:10010 true ex 10 nx
设置加锁的最大时长为60s,如果60s内还没有完成业务逻辑处理,就释放锁了。当然,实际生产过程中,我们有很多手段防止业务逻辑还没有处理完就释放锁(锁续命,redisson已经实现了),我们这条命令主要是防止程序意外终止而导致死锁。 - 计数器
incr
例如,我的csdn 博客文章的查看人数。查看一次下面的数字就加1,数据结构可以这样设计,incr wenzhang:10 - 分布式系统全局序列号
incrby pid 10000 //批量生成序列号可以提升性能
三、hash常用方法和使用场景
1.hash常用方法
HSET key field value //存储一个哈希表key的键值
HSETNX key field value //存储一个不存在的哈希表key的键值
HMSET key field value [field value ...] //在一个哈希表key中存储多个键值对
HGET key field //获取哈希表key对应的field键值
HMGET key field [field ...] //批量获取哈希表key中多个field键值
HDEL key field [field ...] //删除哈希表key中的field键值
HLEN key //返回哈希表key中field的数量
HGETALL key //返回哈希表key中所有的键值
HINCRBY key field increment //为哈希表key中field键的值加上增量increment2.hash使用场景
- 对象缓存(如果是缓存对象的多个字段,并且经常修改,用哈希结构比string结构性能更高)
hmset user {userId}:name fafa {userId}:age 18 - 购物车场景
1 用户id 为key
2 商品id为field
3 商品数量value
购物车操作:
添加商品:hset cart:20 10010 1
添加数量:hincrby cart:20 10010 10
商品总数:hlen cart:20
删除商品:hdel cart:20 10013
获取购物车所有商品:hgetall cart:20
命令操作:
四、list常用方法和使用场景
1.list常用方法
List常用操作
LPUSH key value [value ...] //将一个或多个值value插入到key列表的表头(最左边)
RPUSH key value [value ...] //将一个或多个值value插入到key列表的表尾(最右边)
LPOP key //移除并返回key列表的头元素
RPOP key //移除并返回key列表的尾元素
LRANGE key start stop //返回列表key中指定区间内的元素,区间以偏移量start和stop指定
BLPOP key [key ...] timeout //从key列表表头弹出一个元素,若列表中没有元素,阻塞等待 timeout秒,如果timeout=0,一直阻塞等待
BRPOP key [key ...] timeout //从key列表表尾弹出一个元素,若列表中没有元素,阻塞等待 timeout秒,如果timeout=0,一直阻塞等待2.list使用场景
- 常用的数据结构
Stack(栈):lpush + lpop 或者 rpush + rpop
Queue(队列):lpush + rpop 或者 rpush + lpop
Blocking MQ(阻塞队列):lpush +brpop 或者 rpush + blpop
栈:
队列:
阻塞队列:
我们先看一张图片
微信订阅号相信大家都应该不陌生吧!这里我订阅了程序员专栏和 java技术江湖两个大咖。只要是我订阅了的人,他们每次发完文章,就把他们文章的id加入到我的列表中,这样,每次进到我的微信的时候,从这个list中再去拿。这就是list的使用场景。例如:
程序员专栏发文章了,id为 111
lpush msg:{tuofafaId} 111
java技术江湖发文章了,文章id为112
lpush msg:{tuofafaId} 112
最后获取最新消息或者前几条消息:lrange msg:10 0 4
操作如下图所示:
五、set常用方法和使用场景
1.set常用方法
Set常用操作
SADD key member [member ...] //往集合key中存入元素,元素存在则忽略,
若key不存在则新建
SREM key member [member ...] //从集合key中删除元素
SMEMBERS key //获取集合key中所有元素
SCARD key //获取集合key的元素个数
SISMEMBER key member //判断member元素是否存在于集合key中
SRANDMEMBER key [count] //从集合key中选出count个元素,元素不从key中删除
SPOP key [count] //从集合key中选出count个元素,元素从key中删除
Set运算操作
SINTER key [key ...] //交集运算
SINTERSTORE destination key [key ..] //将交集结果存入新集合destination中
SUNION key [key ..] //并集运算
SUNIONSTORE destination key [key ...] //将并集结果存入新集合destination中
SDIFF key [key ...] //差集运算
SDIFFSTORE destination key [key ...] //将差集结果存入新集合destination中2.set使用场景
- 抽奖场景
抽奖大家平时在生活中肯定都有参与过。过程这里就不详细介绍了。一般抽奖,我们首先肯定要让用户加入到抽奖的集合中,也就是要参与进来。还要提供查看所有参与抽奖的用户,再就是抽奖了。
加入抽奖:sadd cj user
查看参与抽奖人:smembers cj
抽奖:srandmember cj 3 或者使用 spop cj 3 ,两者的区别是前者抽完奖后还留在集合中(还可以继续抽其他奖),后者从集合中已经删除了(不能在参与了其他的奖了)
加入抽奖: - 查看所有参与抽奖的用户:
- 抽奖:
- 微信微博的点赞
点赞:sadd like:{消息id} {用户id}
取消点赞:srem like:{消息id} {用户id}
检查用户是否点过赞:sismember like:{消息id} {用户id}
获取点赞的用户列表:smembers like:{消息id}
获取点赞的用户数: scard like:{消息id}
命令操作如下:- 集合操作
此外,set还可以完成数学中的集合操作。求一些交集、并集和差集
我们设计这样一个环境,假设此时有三个集合A、B、C。集合A中有a,b,c。集合B中 b,c,d。集合C中有 c,d,e。
求集合A,B,C的交集:sinter A B C
求集合A,B,C的并集:sunion A B C
求集合A,B,C的差集:sdiff A B C (返回A集合在B和C集合中不存在的元素)
命令操作如下: - 集合操作实现微博微信关注模型
上一张图来说明关注模型 - 这个场景也很常见。这就是我们所说的关注模型。我关注了谁,谁关注了我,我关注的也关注了谁,我们可能认识的人等等都是set的应用场景。例如:






fafa关注的人:fafaSet-->{dt,gxr}
suosuo关注的人:suoSet-->{dt,gxr,lmm,fafa}
彭远关注的人:pySet-->{dt,suosuo,lmm,fafa,nn}
我和suosuo共同关注的人:sinter fafaSet suoSet --->{dt,gxr}
我关注的人也关注了他(suosuo):
sismember dtSet suosuo
sismember gxrSet suosuo
这一项可能有点绕,仔细分析还是可以的。我关注的人也关注了suosuo,那就检查一下我关注的人的集合中是否存在suosuo。有就说明关注了,否则就没有关注。
我可能认识的人:
sdiff pySet fafaSet --->{suosuo,lmm,fafa,nn}六、zset常用方法和使用场景
1.zset常用方法
ZADD key score member [[score member]…] //往有序集合key中加入带分值元素
ZREM key member [member …] //从有序集合key中删除元素
ZSCORE key member //返回有序集合key中元素member的分值
ZINCRBY key increment member //为有序集合key中元素member的分值加上increment
ZCARD key //返回有序集合key中元素个数
ZRANGE key start stop [WITHSCORES] //正序获取有序集合key从start下标到stop下标的元素
ZREVRANGE key start stop [WITHSCORES] //倒序获取有序集合key从start下标到stop下标的元素
Zset集合操作
ZUNIONSTORE destkey numkeys key [key ...]//并集计算
ZINTERSTORE destkey numkeys key [key …] //交集计算2.zset使用场景
- zset集合操作实现排行榜
还是通过一张图说明使用场景:

六、总结
Redis的使用场景还是非常丰富的。总结下来也就是缓存、计算和分布式锁。因为这篇文章重点在于Redis数据结构的常用方法和实战场景介绍,所以,对于分布式锁后面还会在单独写一篇文章。
















