Redis 核心数据结构
Redis 具有五种核心数据结构。
- String 结构,该结构用来存储字符串数据。
- Hash 结构,该结构用来存储key value 键值对,可以理解为嵌套map 。
- List 列表,该结构用来存储列表数据,还可以用来当做队列结构,和栈结构。
- Set集合,该结构存储的数据不允许重复。
- 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 和 数量 。

优缺点
优点 :
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
交集运算
指令 : 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
这时候数据应该是这样的
并集运算
指令 : 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并集计算,生成近期排行榜。