(一)五大基础数据结构
A. string
- 概述:字符串是最基础的数据结构,redis所有的key都是string类型,且其他的数据结构都是基于string构建的。redis中string的value可以是string、数字(int float)甚至是二进制(图片、音频 & 视频),其value最大值不超过512MB。
- 主要操作
- 设置 & 获取value
- 基础设置:直接使用
set key value。 - 过期设置:原子操作使用
setex key seconds value。 - 条件设置:设置key不存在时才能被新建,使用
setnx key value。 - 注意:若多个clients同时执行setnx,仅有一个client可设置成功(setnx即为redis中分布式锁的实现方案,具体实现请参考redis官方文档)。
- 获取value:
get key获取对应value,若不存在则会返回nil。
- 基础设置:直接使用
- 批量操作
- 概述:提高业务处理效率,降低网络压力,但是单次批量操作不宜发送过多命令,容易导致redis阻塞和网络拥塞。
- 批量设置
mset key1 value1 key2 value2 key3 value3。 - 批量获取
mget key1 key2 key3。
- 计数操作
- 概述:incr命令对value进行自增操作,若value不是整数则返回错误,若key不存在则从0开始增加(第一次执行完就为1)。
- 基础命令为
incr key&decr key - 指定增加数目:
incrby key increment
- 低频使用命令
- 追加值:
append key value,比如原始的key对应的value是redis,使用了append key world后,value变成了redisworld。 - value的长度:
strlen key,单个中文被认为长度为3。
- 追加值:
- 设置 & 获取value
- 主要功能
- 缓存功能,免于直接调用database;
- 计数功能,基于incr实现;
- 共享session,因为web服务存在负载均衡的问题,一个用户多次访问可能会被分配至不同server。redis会存储所有server的session,统一获取;
- 限速,基于计数器的本质,确保一定时间内只能发送数次请求
// 60s内只能尝试1次(比如短信验证场景) phoneNum = "1886*12***9"; key = "msgLimitation:" + phoneNum; // setex 设置参数NX确保是全新的key才设置value为0 isExists = redis.set(key, 0, "EX 60", "NX"); if(isExists != null & redis.incr(key) <= 1) { //通过,第2次进入的时候进行语法判断,发现key的value变成了2,会进入下方限速区域 } else { // 限速不通过 }
B. hash
概述:redis内的hash类型的value包含多个fileds。比如key是user:10086,value里面有2个fields分别是name & age,具体对应的value是dave & 18。
-
主要操作
- 设置 & 获取value
- 基础设置:
hset key field value,设置成功会返回1,否则返回0。 - 条件设置:当这个field不存在时才可被新建,使用
hsetnx key field value实现。 - 获取value:
heget key field
- 基础设置:
- 删除fields:
hdel key field1 [field2],删除全部fields则该hash key就消失了。 - 计算长度
-
hlen key,可获得该key下的fields总数,便于粗略判断key的大小。 -
hstrlen key field,计算key的具体某个field的value的长度。
-
- 批量操作
- 批量获取即
hmget key field1 [field2]。 - 批量设置即
hmset key field1 value1 [field2 value2]。
- 批量获取即
- 判断field存在与否:
hexists key field,根据存在与否返回1或0。 - 全量获取
- 全部fields:使用
hkeys key可看到key对应的所有fields,hlen key只能看到field的总数,不能看到具体内容。 - 全部values:
hvals key获得key对应的所有values。 - 全量内容:
hgetall key可以看到key下所有的fields和对应的values。
- 全部fields:使用
- 计数器:作用域也是对于key下具体的某个field,语法为
hincrby key field。
- 设置 & 获取value
优点:占用键少,合理使用可以减少内存消耗
C. list
- 概述:列表数据结构中的元素是有序的,且元素可以重复。
- 主要操作
- 基础操作
- 头部添加:即左侧插入,
lpush key value1 [value2] - 尾部添加:即右侧插入,
rpush key value1 [value2] - 某元素位置添加:
insert key before pivot value或者insert key after pivot value,在list元素为pivot前或后插入value元素。 - 头部弹出:即取出最左侧元素,
lpop key - 尾部弹出:即取出最右侧元素,
rpop key - 删除指定元素:
lrem key count value,删除count个key中等于value的元素。count > 0,从左往右删,count < 0则从右往左删,count=0全删。 - 范围删除:
ltrim key start end,仅保留start到end的部分,其他都删掉。 - 修改:
lset key index newValue对具体某个下标的元素做修改。 - 列表的长度:
llen key
- 头部添加:即左侧插入,
- 查找
- 获取全部元素:
lrange key start end,例如lrange test 0 -1即把名为test的list的全部元素罗列出来。 - 获取指定元素:
lindex key index
- 获取全部元素:
- 阻塞操作
- 弹出:
blpop key1 key2 timeout或者brpop key1 key2 timeout,可对多个列表同时弹出,timeout设置为0代表会一直保持阻塞,一有新元素进入就弹出。若多个client都是用命令,则先触发命令的获得弹出内容。
- 弹出:
- 基础操作
- 主要功能:
- 消息队列:lpush + brpop的组合可实现阻塞队列(FIFO),生产者使用lpush,消费者使用brpop抢元素。若组合改为lpush + blpop即为栈。
- 文章列表:每个用户有自己阅读的文章列表。
- 文章本身是用hash存储的,比如
hmset article:1 title xx time 12321 content yyyy,hmset article:2 title zz time 12298 content nhs - 设置用户1号选手所阅读的文章列表,
lpush user:1:articles article:1 article:2
- 文章本身是用hash存储的,比如
D. set
- 概述:集合中无重复元素,且内部是无序的,无法通过index获取元素内容。
- 主要操作
- 基础操作
- 添加元素:
sadd key element1 [element2],无需和hash一样必须使用hmset才能设置多个field-value。 - 删除元素:
srem key element1 [element2]。 - 随机弹出元素:
spop key - 计算元素个数:
scard key,类似hlen的效果。 - 获取全量元素:
smembers key
- 添加元素:
- 查找
- 判断是否存在某元素:
sismember key element - 随机返回:
srandmember key [count],count若不填写,则返回一个元素,填了就根据数字返回。
- 判断是否存在某元素:
- 集合间操作
- 交集:
sinter key1 key2 [key3] - 并集:
sunion key1 key2 [key3] - 差集:
sdiff key1 key2 [key3],差集的含义是key1集合中有,但其他集合中没有的。 - 存下结果:
sinterstore newkey key1 key2 [key3],把结果存到newkey这个set中。
- 交集:
- 基础操作
- 主要功能:给用户添加标签,或给某类标签添加用户
- 注意:smembers,lrange,hgetall都是时间复杂度高的命令,建议用sscan
E. sorted_set
- 概述:保留了set的元素不重复这一特性,但是有序集合内的元素可进行排序,依据每个元素的score(多用于排行榜的场景)
- 主要操作
- 基础操作
- 添加成员:
zadd key score1 member1 [score2 member2]可添加其余参数,例如nx xx(类似setnx) - 删除成员:
zrem key member1 [member2] - 删除排名内成员:
zremrangebyrank key start end,删除升序排名start-end内的成员。 - 删除分数内成员:
zremrangebyscore key min max - 计算成员个数:
zcard key - 某分数段内成员个数:
zcount key min max - 增加成员分数:
zincrby key increment member
- 添加成员:
- 查找 & 排名
- 获取某个成员的分数:
zscore key member - 返回排名范围的成员:
zrange key start end [withscores]&zrevrange key start end [withscores],带上参数后返回结果会有score显示。 - 返回分数范围的成员:
zrangebyscore key min max [withscores] [limit offset count],同样也有zrevrangebyscore。 - 计算成员排名:
zrank key member&zrevrank key member,前者是从低到高排名,后者反之。
- 获取某个成员的分数:
- 集合间操作
- 交集:
zinterstore newkey numkeys key1 [key2],newkey即结果保存到这个新集合中,numkeys意味着需要做交集计算的个数。 - 并集:
zunionstore newkey numkeys key1 [key2]
- 交集:
- 基础操作
- 主要功能:一般用于排行榜系统,下方以点赞为场景进行展示
- 添加用户赞数:
zadd user:ranking:2022_07_03 3 mike,每天有一个rank的有序集合,在2022.07.03的排行榜上,用户mike有3个赞。 - 后续点赞设计:
zincrby user:ranking:2022_07_03 1 mike,后续每点一个赞就score+1。 - 取消赞设计:若用户注销,需删除时使用
zrem user:ranking:2022_07_03 mike,此时mike被删除。 - 展示点赞排行榜:展示top10的点赞用户和他们的具体点赞数,则使用
zrevrange user:ranking:2022_07_03 0 9 withscores。 - 展示某个用户的排名和点赞数:排名为
zrank user:ranking:2022_07_03 mike,点赞数为zscore user:ranking:2022_07_03 mike。
- 添加用户赞数: