原文地址 👉 欢迎访问我的个人博客 👈
Redis 数据结构的常用基本操作。
官方文档是最全面的,这里只记录一些常用命令。
1. String
1.1 存值
存入单个字符串键值对:
set [key] [value]
批量存入键值对:
mset key value [key] [value]
存入一个不存在的键值对,若redis中已存在则不创建:创建成功返回1,失败返回0
setnx key value
设置一个键的过期时间:(单位:秒)设置成功返回1,失败返回0
expire key seconds
1.2 取值
单键值取值:
get key
批量键值取值:
mget key [key] ...
1.3 删值
删除一个或多个键值:返回成功删除的个数
del key [key] ...
1.4 原子操作
数字键值对的值加1:返回加1后的值;不存键值对则新建一个,返回初始值1
incr key
数字键值对的值减1:返回减1后的值;不存键值对则新建一个,返回初始值-1
decr key
数字键值对的值加上期望值:返回加上期望值后的值;不存键值对则新建一个,返回初始值(期望值)
incrby key increment (期望值)
数字键值对的值减去期望值:返回减去期望值后的值;不存键值对则新建一个,返回初始值(期望值)
incrby key increment (期望值)
1.5 应用
1.5.1 对象缓存
将对象Object数据转化为JSON格式存进redis
set user:john data(json格式)
1.5.2 分布式锁
例如,对某一产品业务加锁:加锁成功返回1,否则0
setnx product:001 true
业务完成后释放锁:
del product:001
防止程序终止导致死锁:ex(过期时间,单位秒) nx(当不存在该键值对是才创建,功能参考setnx)
set product:001 true ex 10 nx
1.5.3 计数器
incr
可用于某些非关键业务数据的计数,例如文章点赞数、阅读数等等。
1.5.4 Session 集群共享
可以将 session 存储到 redis 实现 session 共享
1.5.5 分布式批量全局序列号
可以给每台机器分配固定索引起的序列号提升性能。
incrby orderId 1000
2. Hash
2.1 存值
单个或多个键值存储:返回成功存储的个数
hset key field value [field value]
e.g.
hset test:user name john age 18 # 返回2
多个键值对存储:
hmset key field value [field value]
存储一个不存在的键值对:若key不存在,先创建 key 再创建 field;若key存在,判断field是否存在,若不存在则创建,否则忽略。
hsetnx key field value
2.2 取值
获取key单个键值对取值:
hget key field
批量获取key里面多个field的值:
hmget key filed [field]
获取key中field的数量:返回 key 中的 filed 总数
hlen key
获取key中所有filed的键与值:键与值成对取出
hgetall key
2.3 删值
删除key的一个或多个键值:返回删除的field键值数量
hdel key field [field]
例如,删除用户Mike的名字和性别field
2.4 原子操作
对key中指定field加上增量increment: 返回增量后的结果
hincrby key field increment
例如,给某个用户年龄+1
2.5 应用
2.5.1 对象缓存
可以直接将对象属性存储到缓存中:
hmset user:mike name mike age 18 gender man
2.5.2 电商商品
存储和调整电商商品数量:
# 添加商品
hset product:001 100001 1
# 增加商品数量
hincrby product:001 100001 1
# 商品总数
hlen product:001
# 删除商品
hdel product:001 100001
# 获取所有商品
hgetall product:001
优点:
节省空间和CPU:利用hash可以很好的归档同一类数据,如果使用 string 的话导致 key 数量过多和操作过多。
缺点:
expire 过期设置无法设置在 filed 上,只能设置 key;不适合集群使用。
3. List
3.1 存值
将一个或多个的元素从左边插入头部:返回当前list的长度
lpush key element [element]
例子的数据结构:
将一个或多个元素从右边插入尾部:返回当前list的长度
rpush key element [element]
3.2 取值和删除
移除元素时如果list没有任何元素则移除list key。
移除并返回指定索引的元素:
lindex key index
移除并返回list头部的元素:
lpop key
移除并返回list尾部的元素
rpop key
获取指定索引区间内的元素(注意:该操作不会删除list内的元素)
lrange key start stop
获取list的长度:
llen key
移除并返回左边头部一个元素,若list没有元素则阻塞等待。(设置 timeout 等待时间,timeout=0时一直阻塞):返回目标list key和目标元素
blpop key [key] timeout
移除并返回右边尾部一个元素,若list没有元素则阻塞等待。(设置 timeout 等待时间,timeout=0时一直阻塞):返回目标list key和目标元素
brpop key [key] timeout
没有元素取出时(不存在 list key),取出操作会被阻塞:直到其有值可取出为止。
3.3 应用
3.3.1 常用的数据结构
- 栈(Stack):LPUSH + LPOP 先进后出
- 队列(Queue):LPUSH + RPOP 先进先出
- 阻塞队列(Blocking Queue):LPUSH + BRPOP 先进先出(阻塞)
3.3.2 类似微信公众号的消息流
公众号1先群发一条消息然后公众号2群发一条消息给用户 user1
lpush message:user1 hello1
lpush message:user1 hello2
用户的收到的消息队列:
那么用户界面呈现最新的消息内容顺序应该是最新的在最底部显示:
# 获取最新消息,假设取10条消息
lrange message:user1 0 10
类似效果:
4. Set
Redis 的 Set 是基于 Inset 和 HashTable的无序集合。
4.1 存值
存储一个或多个元素,若元素已存在忽略;若key不存在则新建:返回成功添加元素的个数
sadd key member [member]
4.2 取值
获取set所有元素:
smembers key
获取set元素个数:
scard key
判断元素是否存在set中:存在返回1,不存在返回0
sismember key menber
从set中取出count个元素(元素不会被删除)
srandmember key count
从set中取出count个元素(元素会被删除)
spop key count
迭代 set 中匹配到的元素;cursor:迭代游标(从0开始),pattern:匹配的元素,count:匹配的数量
返回该次迭代匹配到的元素和下一次的迭代游标。
sscan key cursor [MATCH pattern] [COUNT count]
例如存在set数据集:需要查找所有匹配 mike*的元素。每次迭代匹配元素个数为2
注意:初始迭代游标是0,每次迭代的游标位置不一样,知道下次迭代游标为0时,迭代匹配过程结束。
迭代匹配过程:
4.3 删值
删除 set 中一个或多个元素:返回成功删除的元素个数
srem key member [member]
4.4 运算操作
多个set交集运算:
sinter key [key...]
多个set交集运算,并将交集结果存到新的set中,返回交集的个数
sinterstore destination key [key...]
例如:set:001 (元素:a,b,c),set:002(元素:b,c)。取交集到新集合set:003(元素:b,c)中
多个set并集运算:
sunion key [key...]
多个set并集运算,并将并集结果存到新集合中
sunionstore destination key [key...]
多个set差集运算
sdiff key [key...]
多个set差集运算,并将差集结果存到新集合中
sdiffstore destination key [key...]
3.5 应用
3.5.1 随机抽奖
# 添加参加抽奖的用户
sadd surprise:001 user1 user2 usre3
# 查看所有参加抽奖的用户
smembers surprise:001
# 随机抽取10位幸运用户
srandmember surprise:001 10
3.5.2 点赞、收藏功能
例如头条朋友圈message(id: 001)点赞
# 参与点赞的用户
sadd message:like:001 user1
# 查看所有点赞的用户(比如朋友圈本人查看)
smembers message:like:001
# 某个用户是否点赞
sismember message:like:001 user1
3.5.3 关注功能
例如用户Mike、John、Cindy
# user1 关注了Mike
sadd mike:like user1
# 关注Mike的用户
srandmembers mike:like
# Mike和John同时关注的用户
sinter mike:like john:like
# 假设John关注了Cindy ,Mike是否也关注了Cindy ?
sismember cindy:like mike
# Mike可能认识的人, Mike和John关注的人差集
sdiff mike:like john:like
5. ZSet
ZSet 可以理解为Set的有序集合。
5.1 存值
添加一个或多个带分值的元素
zadd key score member
例如:添加Mike成绩80
zadd score:math 80 mike
指定集合中元素添加增量值:返回增值后的数据
zincrby key increment member
5.2 取值
获取集合中的元素个数
zcard key
获取集合中元素的分值
zscore key member
正序获取指定下标区间的元素
zrange key start stop
倒序获取指定下标区间的元素:withscores(是否同时查询value分值)
zrevrange key start stop [withscores]
5.3 删值
从集合中删除一个或多个元素
zrem key member [member]
5.4 运算操作
获取两个以上集合的并集: numkeys 指需要执行运算操作的集合数
zunion numkeys key [key]
获取两个以上集合的交集
zinterstore numkeys key [key]
获取两个以上集合的并集,并将结果存储到新集合。destKey 指运算操作后存储结果新建的集合
zunionstore destkey numkeys key [key]
获取两个以上集合的交集,并将结果存储到新集合。
zinterstore destkey numkeys key [key]
5.5 应用
5.5.1 排行榜
因为Zset 是有序集合,所以可以应用到一些和排序有关的业务场景,例如排行榜:
# 获取某日新闻排行榜前十 (返回0-9条field+value数据)
zrevrange news:20220212 0 9 withscores
# 七日排行榜
zunionstore news:20220201-20220209 7 news:20220201 news:2022:0202 ...
# 七日排行榜前十
zrevrange news:20220201-20220209 0 9 withscores