Redis 支持哪些数据结构?
- 「字符串」(string):字符串是 Redis 最基本的数据结构,它可以是普通的字符串或者二进制数据,最大长度为512MB。
- 「哈希」(hash):Redis哈希是一个键值对集合,其中键和值都是字符串类型。哈希适用于存储对象。
- 「列表」(list):Redis列表是一个链表,每个节点都包含了一个字符串,列表支持正反两个方向的遍历。
- 「集合」(set):Redis集合是字符串的无序集合,支持添加、删除、判断元素是否存在等基本操作,还支持交、并、差等操作。
- 「有序集合」(sorted set):Redis有序集合和集合类似,区别在于集合中的元素可以关联一个分数(score),根据分数进行排序。
img
redis数据结构的使用
接下来叙述常用的api和应用场景。
字符串
「常用操作」
- 存入字符串键值对:SET key value
- 批量存储字符串键值对:MSET key value [key value ...]
- 存入一个不存在的字符串键值对:SETNX key value
- 获取一个字符串键值:GET key
- 删除一个键:DEL key [key ...]
- 设置一个键的过期时间(秒):EXPIRE key seconds
「原子操作」
- 将key中储存的数字值加1:INCR key
- 将key中储存的数字值减1:DECR key
- 将key所储存的值加上i:INCRBY key i
- 将key所储存的值减去d:DECRBY key d
「应用场景」
- 对象缓存:
我们把user表的数据存储到redis中,(user:id)作为key:SET user:1001 value(user的JSON数据)。
也可以将(user:id :字段名)作为key:
SET user:1001:name 小明,
MSET user:1001:name 小明 user:1001:age 18。
- 分布式锁:
利用SETNX命令存入不存在的字符串值,如果key不存在,SETNX将key的值设置为value,然后返回1。如果key已经存在,SETNX不会改变任何内容,并返回0,获得锁后代码运行完毕,删除锁DEL 。
为了防止死锁现象一般设置锁超时时间。我们可以使用SET命令配合NX(如果不存在则设置)和EX(设置过期时间,单位为秒)选项来达到同样的效果,
SET user:1001 value NX EX 10
- 计数器
利用INCRBY原子加操作,可以对文章的阅读量技术。
INCRBY article:readCount:1001
- 分布式序列号
也是利用INCRBY去生成序列号。
哈希Hash
「常用操作」
它的结构大概是 key filed:value,两层,一个是key,一个是filed。
- 存储一个哈希表key的键值:HSET key field value
- 存储一个不存在的哈希表key的键值:HSETNX key field value
- 在一个哈希表key中存储多个键值对:HMSET key field value [field value ...]
- 获取哈希表key对应的field键值:HGET key field
- 批量获取哈希表key中多个field键值:HMGET key field [field ...]
- 删除哈希表key中的field键值:HDEL key field [field ...]
- 返回哈希表key中field的数量:HLEN key
- 返回哈希表key中所有的键值:HGETALL key
「原子操作」
- 为哈希表key中field键的值加上增量i:HINCRBY key field i
- 为哈希表key中field键的值减去d:DECRBY key field d
「应用场景」
- 对象缓存
HSET user 1001:name 小明 1001:age 18 1002:name 小红
HMGET user 1001:name 1001:age 1002:name
- 电商购物车
以(cart:用户ID)为key,商品id为filed,数量为value。
添加商品:
hset cart:1001 pro_100 1
增加数量:
HINCRBY cart:1001 pro_100 1
商品总数:
HLEN cart:1001
删除商品:
hdel cart:1001 pro_100
获取购物车所有商品:
HGETALL cart:1001
List
集合
「常用操作」
- 将一个或多个值value插入到key列表的表头(最左边):LPUSH key value [value ...]
- 将一个或多个值value插入到key列表的表尾(最右边):RPUSH key value [value ...]
- 移除并返回key列表的头元素:LPOP key
- 移除并返回key列表的尾元素:RPOP key
- 返回列表key中指定区间内的元素,区间以偏移量start和stop指定:LRANGE key start stop
- 从key列表表头弹出一个元素,若列表中没有元素,阻塞等待timeout秒,如果timeout=0,一直阻塞等待:BLPOP key [key ...] timeout
- 从key列表尾部弹出元素,若列表中没有元素阻塞等待:BRPOP key [key ...] timeout
list
「应用场景」
栈 先进后出 = LPUSH + LPOP
队列 先进先出 = LPUSH + RPOP
阻塞队列 = LPUSH + BLPOP
SET
不重复集合
「常用操作」
- 往集合key中存入元素,元素存在则忽略:SADD key member [member ...]
- 从集合key中删除元素:SREM key member [member ...]
- 获取集合key中所有元素:SMEMBERS key
- 获取集合key的元素个数:SCARD key
- 判断member元素是否存在于集合key中:SISMEMBER key member
- 从集合key中随机选出count个元素(默认是1个),元素不从key中删除:SRANDMEMBER key [count]
- 从集合key中随机选出count个元素(默认是1个),元素从key中删除:SPOP key [count]
「set运算操作」
交集运算:SINTER key [key ...]
交集运算
将交集结果存入新交集set3中:SINTERSTORE set3 key [key ..]
存放新交集set3中
并集运算:SUNION key [key ..]
将并集结果存入新集合set4中:SUNIONSTORE set4 key [key ...]
差集运算:SDIFF key [key ...]
将差集结果存入新集合set5中:SDIFFSTORE set5 key [key ...]
「应用场景」
- 抽奖:
添加用户:SADD key member
抽奖:SRANDMEMBER award:100 或者 SPOP award:100
- 朋友圈查看点赞
只能看见好友的点赞。
点赞:SADD userID:like:内容 用户id
取消点赞:SREM userID:like:内容 用户id
判断是否点赞过:SISMEMBER userID:like:内容 用户id
朋友看都有谁点赞了:SINTER userID:like:内容 自己的朋友ID
可能认识的人:SDIFF 朋友的朋友ids 我的朋友ids(属于朋友的朋友,但不属于我的朋友的集合)
ZSET
不重复有序集合
「常用操作」
每个值都有自己的分值,比如说 小明 80分,小红 70分,插入班级数学成绩集合。
score:80,70。member:小明,小红
- 往有序集合key中加入带分值元素:ZADD 数学成绩集合 80 小明 70 小红 [[score member]…]
- 从有序集合key中删除元素:ZREM key member [member …]
- 返回有序集合key中元素member的分值:ZSCORE key member
- 为有序集合key中元素member的分值加上i:ZINCRBY key i member
- 返回有序集合key中元素个数:ZCARD key
- 正序获取有序集合小到大key从start下标到stop下标的元素:ZRANGE key start stop [WITHSCORES] WITHSCORES:WITHSCORES 是一个可选参数,用于指定 Redis 命令的返回结果是否包含成员的分数值。 负数表示从后往前数。
- 倒序获取有序集合大到小key从start下标到stop下标的元素:ZREVRANGE key start stop [WITHSCORES]
「集合运算」
并集计算:
ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]
- destination 是存储结果的新的有序集合的名称。
- numkeys 是输入的有序集合的数量。
- key 是输入的有序集合的名称,可以指定多个。
- WEIGHTS 是一个可选参数,后面可以跟随一个或多个权重值,用于调整输入的有序集合的分数。如果指定了 WEIGHTS,其数量必须与输入的有序集合数量相同。默认情况下,所有的输入有序集合的权重都是 1。
- AGGREGATE 是一个可选参数,用于指定如何聚合相同元素的分数。可以是 SUM(默认值)、MIN 或 MAX。
WEIGHTS后跟num,那么对应的有序列表的值就需要乘以它。
AGGREGATE表示如果多个列表中有相同的元素,那么他们的值是相加、取最小、取最大。
ZUNIONSTORE zset3 2 zset1 zset2 WEIGHTS 2 3 AGGREGATE MIN
这段指令得意思是,zset1 zset2求交集,并将结果集覆盖到zset3集合里边(zset3如果有值也会被删除)。wergth:会把zset1的所有值乘2,zset2的所有值乘3。AGGREGATE MIN 如果键有重复,选取最小的那个,如图中的键aaa。
交集计算:
ZINTERSTORE destkey numkeys key [key …] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]
- destkey 是存储结果的新的有序集合的名称。
- numkeys 是输入的有序集合的数量。
- key 是输入的有序集合的名称,可以指定多个。
「应用场景」
微博热搜:
新增一条新闻:ZADD news 0 news:20230623:101
点击新闻增加热度:ZINCRBY news 1 news:20230623:101
七日搜索榜单计算:ZUNIONSTORE hotNews:17-23 7 news:20230623:101 news:20230622:101 ... ...
展示七日排行前十:ZREVRANGE hotNews:17-23 0 9 WITHSCORES