Redis 核心数据结构

Redis 具有五种核心数据结构。

  1. String 结构,该结构用来存储字符串数据。
  2. Hash 结构,该结构用来存储key value 键值对,可以理解为嵌套map 。
  3. List 列表,该结构用来存储列表数据,还可以用来当做队列结构,和栈结构。
  4. Set集合,该结构存储的数据不允许重复。
  5. ZSet集合,该结构是一个有序的Set集合,排序条件是分值Scores 。

Redis String数据结构

字符串常用操作

插入字符串键值对
指令: set key value 

例如:  set user:zhangsan 10086
批量插入字符串键值对
指令: mset key value key value ....

例如: mset user:zhangsan 10086  user:lisi 10010 user:wangwu 10000
插入不存在的键值对
指令 : setnx key value

例如 : setnx commodity:100 uid56

该功能可以用作轻量级的分布式锁,当执行指令后,redis会判断是否数据已存在,如果不存在则新增数据并且返回1,否则返回0。

当线程获取到返回1后才可以继续执行业务,并且要在执行完毕后删除该key,也就是释放锁。

以防万一线程挂了的情况下造成死锁,理应给key加上超时时间,让redis自行删除超时数据。

获取单个字符串数据
指令 : get key 

例如 : get  user:zhangsan
批量获取字符串数据
指令 : mget key key ....

例如 : mget user:zhangsan user:lisi user:wangwu
删除key
指令 : del key key ....

例如 : del user:zhangsan user:wangwu
设置key的超时时间
指令 : expire  key  seconds

例如 : expire  commodity:100  10

原子增减

对数据原子增 1
指令 : incr key

例如 : incr commodity:share
对数据原子减 1
指令 : decr key 

例如 : decr commodity:share
对数据原子增 指定数值
指令 : incrby key increment 

例如 : incrby commodity:share 1000
对数据原子减 指定数值
指令 : decrby key increment

例如 : decrby commodity:share 1000

应用场景

1、计数器,例如点赞次数 、分享次数、预览次数 。

2、Web集群session共享

3、分布式系统全局自增序列

Redis Hash数据结构

Hash常用操作

存储哈希表key的键值
指令 : hset  key  field  value

例如 : hset commodity:100 name 蛋黄酥
插入不存在的哈希表键值对
指令 : hsetnx  key  field  value

例如 : hsetnx commodity:100 edit uid56

同String结构,当Redis中没有该数据时,会新增并返回1.否则返回0 。

存储多个键值对
指令 : hmset  key  field  value field  value ...

例如 : hmset commodity:100 name 蛋黄酥 price 10
获取哈希表key中的键值对数量
指令 : hlen  key

例如 : hlen  commodity:100
获取哈希表key中的单个field对应的value
指令 : hget key field

例如 : hget commodity:100 edit
获取哈希表key中的多个field对应的value
指令 : hmget key field field

例如 : hmget commodity:100 edit share
获取哈希表key中的所有键值数据
指令 : hgetall  key

例如 : hgetall commodity:100
对哈希表key中field的value数据原子增
指令 : hincrby  key  field  increment

例如 : hincrby commodity:100 share 100
删除哈希表key中的键值对
指令 : hdel key field field field....

例如 : hdel commodity:100 name price

应用场景

对象缓存

例如购物车,用户id为key值,field为商品id,value 为加入购物车的数量。

当用户操作商品数量时,对value进行原子增、原子减。

hlen 命令获取购物车数量,hgetall获取所有购物车商品id 和 数量 。

WX20200608-231646@2x

优缺点

优点 :

1、同类数据归类整合储存,方便数据管理
2、相比string操作消耗内存与cpu更小
3、相比string储存更节省空间

缺点:

1、过期功能不能使用在field上,只能用在key上
2、Redis集群架构下不适合大规模使用

Redis List数据结构

List 常用操作

插入一个或多个数据到list表头 (最左边 )
指令 : lpush  key  value value ....

例如 : lpush commodity:hot 100 101 102 103
插入一个或多个数据到list表尾 ( 最右边 )
指令 : rpush key value value ...

例如 : rpush commodity:hot 99 98 97
移除并返回表头元素
指令 : lpop key

例如 : lpop commodity:hot
移除并返回表尾元素
指令 : rpop key

例如 : rpop commodity:hot
获取list指定区间的数据
指令 :  lrange  key  start  stop

例如 : lrange commodity:hot 1 3

List 阻塞操作

阻塞弹出表头的元素

从表头弹出一个元素,若没有数据则会等待, timeout是超时时间 ( 单位为秒 ) ,倘若为0的话,则会一直等待。

指令 : blpop  key  timeout

例如 : blpop commodity:hot 10 
阻塞弹出表尾的元素

从表尾弹出一个元素,若没有数据则会等待, timeout是超时时间 ( 单位为秒 ) ,倘若为0的话,则会一直等待。

指令 : brpop key timeout

例如 : brpop commodity:hot 10

应用场景

1、Stack 栈数据结构,先进后出。 lpush + lpop

2、Queue 队列,先进先出。 lpush + rpop

3、Blocking MQ 阻塞队列 先进先出。lpush + brpop

4、业务场景:文章流分页查询,lrange key start stop 查询区间数据 。

Set数据结构

Set集合常用操作

加入数据到Set集合
指令 : sadd key member member...

例如 : sadd commodity:101:collect uid56 uid57 uid58 uid59 uid60

如果数据不存在则新增,并且返回1,否则忽略执行,并且返回0 。

从Set集合中移除数据
指令 : srem key member member...

例如:srem commodity:101:collect uid56 uid57
获取集合中所有元素
指令 :  smembers  key

例如 : smembers  commodity:101:collect
获取集合key的元素个数
指令 :  scard key

例如 : scard commodity:101:collect
判断Set集合中是否存在元素
指令 :  sismember key  member

例如 : sismember commodity:101:collect uid58

存在则返回1,不存在则返回0。

从Set集合随机取出指定数量元素
指令 : srandmember  key count

例如 : srandmember commodity:101:collect 2
从Set集合随机取出指定数量元素,并删除
指令 : spop  key count

例如 : spop commodity:101:collect 2

Set运算操作

先初始化三个Set集合

sadd commodity:101:collect uid56 uid57 uid58

sadd commodity:102:collect uid57 uid58 uid59

sadd commodity:103:collect uid57 uid60 uid61

QQ20200609-114153@2x

交集运算
指令 :  sinter key key ...

例如 : sinter commodity:101:collect commodity:102:collect commodity:103:collect 

交集运算可以在多个集合中,寻找共同的数据,比如这三个集合中都有uid57,所以交集运算结果能能到uid57。

交集运算 生成新的集合
指令 :  sinterstore newkey  key key...

例如 : sinterstore commodity:101-102-103:collect:sinter commodity:101:collect commodity:102:collect commodity:103:collect 

该指令会将其他集合有交集的数据放到新的集合中,如上指令执行后,会生成一个 “commodity:101-102-103:collect:sinter” 集合。

并集运算
指令 :  sunion key  key....

例如 : sunion commodity:101:collect commodity:102:collect commodity:103:collect 

该指令会将多个集合的数据组合成一起返回

并集运算 生成新的集合
指令 :  sunionstore newkey  key key....

例如 : sunionstore commodity:101-102-103:collect:sunion commodity:101:collect commodity:102:collect commodity:103:collect 

该指令会将多个集合的数据组成一个新的集合,如上指令执行后,会生成一个 “commodity:101-102-103:collect:sunion” 集合。

差集运算
指令 : sdiff  key key ....

例如 : sdiff  commodity:101:collect commodity:102:collect commodity:103:collect 

差集运算是以第一个key的集合为基准,与其他集合进行匹配,最后筛选出不在其他集合中的数据。

如上指令执行后,得到的结果是uid56,因为其他两个集合都没有uid56,所以uid56被筛选出来了。

差集运算 生成新的集合
指令 : sdiffstore  newkey  key key...

例如 : sdiffstore commodity:101-102-103:collect:diff commodity:101:collect commodity:102:collect commodity:103:collect 

该指令会将差集数据生成到新的集合中 ,如上指令会生成一个 “commodity:101-102-103:collect:diff ” 的集合。

应用场景

1、列表数据不重复,点赞用户列表、分享用户列表 等等 。

2、随机抽奖,利用srandmember 、spop 指令随机抽取。

3、并集运算、交集运算、差集运算。

ZSet 数据结构

ZSet 常用操作

添加带分值元素
指令 : zadd key score member score member ...

例如 : zadd article:hotlist 100 article1 101 article2 102 article3
删除元素
指令 : zrem key member member...

例如 : zrem article:hotlist article1 article2
查询元素的分值
指令 : zscore key member

例如 : zscore article:hotlist article3
对元素分值增加
指令 : zincrby key increment member

例如 : zincrby article:hotlist 100 article3
获取集合中的元素个数
指令 : zcard key

例如 : zcard article:hotlist 
正序获取区间元素
指令 : zrange key start stop 

例如 : zrange article:hotlist  0 1

如果需要连分值一起获取的话,在指令后面加上withscores即可,例: zrange article:hotlist 0 1 withscores

倒序获取区间元素
指令 : zrevrange  key start stop

例如 : zrevrange  article:hotlist 0 1

ZSet 集合操作

准备两个集合数据

zincrby article:hotlist:20200608 2 article1

zincrby article:hotlist:20200608 1 article2

zincrby article:hotlist:20200608 1 article3

zincrby article:hotlist:20200609 4 article1

zincrby article:hotlist:20200609 2 article2

zincrby article:hotlist:20200609 1 article6

zincrby article:hotlist:20200609 1 article4

zincrby article:hotlist:20200609 1 article3

这时候数据应该是这样的 20200608

20200609

并集运算
指令 :  zunionstore newkey numkeys key key ...

例如 : zunionstore article:hotlist:20200608-20200609  2 article:hotlist:20200608 article:hotlist:20200609

指令中numkeys 用来表示要计算的集合数量。

将多个集合组合起来,并且会叠加分值,生成一个新的集合,如上执行后,会生成新的 “article:hotlist:20200608-20200609” 集合。

交集运算
指令 : zinterstore newkey numkeys key key ...

例如 : zinterstore article:hotlist:insterstore 2 article:hotlist:20200608 article:hotlist:20200609

指令中numkeys 用来表示要计算的集合数量。

将多个集合进行交集运算,并且会叠加分值,生成一个新的集合,如上执行后,会生成新的 "article:hotlist:insterstore" 集合。

应用场景

1、排行榜,通过分值让redis自行排序。

2、近期排行榜,通过redis并集计算,生成近期排行榜。