一、list¶
简介
列表(list)类型是用来存储多个有序的字符串
1、单键多值
2、Redis 列表是简单的字符串列表,按照插入顺序排序。可以添加一个元素到列表的头部(左边)或者尾部(右边)。
3、列表中的元素是有序的
4、底层实际是个双向链表,对两端的操作性能很高,通过索引下标的操作中间的节点性能会较差
5、键值可重复

常用命令
添加
(1)从右/左边插入元素
rpush/lpush key value [value ...]
(2)向某个元素前或者后插入元素
linsert key before|after pivot value
127.0.0.1:6379> linsert listkey before b java
(integer) 4
(3)移除列表key1的最后一个元素,并将该元素添加到另一个列表key2的左边并返回
rpoplpush <key1> <key2>
删除
(1)从列表左/右侧弹出元素
lpop/rpop key
(2)删除指定元素
lrem key count value
-
count>0,从左到右,删除最多count个元素。
-
count<0,从右到左,删除最多count绝对值个元素。
-
count=0,删除所有。
(3)按照索引范围修剪列表
ltrim key start end
127.0.0.1:6379> ltrim listkey 1 3 #只保留列表listkey第2个到第4个元素
OK
(4)阻塞式的删除操作
blpop/brpop key [key ...] timeout
查询
(1)获取指定范围内的元素列表
lrange key start end #左-》右:0到N-1,右-》左:-1到-N
127.0.0.1:6379> lrange listkey 0 -1 #命令可以从左到右获取列表的所有元素
127.0.0.1:6379> lrange listkey 1 3 #获取列表的第2到第4个元素
(2)获取列表指定索引下标的元素
lindex key index
(3)获取列表长度
llen key
修改, 修改指定索引下标的元素
lset key index newValue
127.0.0.1:6379> lset listkey 2 python #将列表listkey中的第3个元素设置为python

数据结构
redis3.2以后将list的压缩列表(ziplist)和双端链表(linkedList)改成了quicklist了。
-
quicklist融合了ziplist和linkedlist的功能;
-
默认一个quicklistNode是一个ziplist对象;
-
ziplist的大小有限制
- 不能保存过多的元素(否则O(n)的查询复杂度会很慢)
- 不能保存过大的元素(过大,装不了几个元素)
- ziplist更新会比较麻烦

ziplist数据结构示意图

quicklist数据结构示意图
-
quicklist解决了压缩列表插入扩缩容的问题(链表指针,不用考虑空间,不用考虑挪移)
-
quicklist解决了压缩列表容量的问题,

应用场景
- 消息队列
- lpush+brpop=Message Queue(消息队列)

-
文章列表
-
其他场景
- lpush+lpop=Stack(栈)
- lpush+rpop=Queue(队列)
- lpush+ltrim=Capped Collection(有限集合)
二、set (集合)¶
简介
1、set对外提供的功能与list类似,是一个列表的功能
2、set是可以无序的
3、set提供了判断某个成员是否在一个set集合内的重要接口,list不能提供
Redis的Set是string类型的无序集合。它底层其实是一个value为null的hash表,所以添加,删除,查找 的复杂度都是O(1)。 一个算法,随着数据的增加,执行时间的长短,如果是O(1),数据增加,查找数据的时间不变
常用命令
集合内操作
(1)添加元素,返回结果为添加成功的元素个数
sadd key member [member ...]
(2)删除元素,返回结果为成功删除元素个数
srem key member [member ...]
(3)计算元素个数
scard key
(4)判断元素是否在集合中
sismember key member
(5)随机从集合返回指定个数元素,不会删除
srandmember key [count] #[count]是可选参数,如果不写默认为1
(6)随机从集合弹出元素删除
spop key [count]
(7)获取所有元素
smembers key
- 集合间操作
(1)求多个集合的交集
sinter key [key ...]
(2)求多个集合的并集
suinon key [key ...]
(3)求多个集合的差集
sdiff key [key ...] #key1中的,不包含key2中的
(4)将交集、并集、差集的结果保存
sinterstore destination key [key ...]
suionstore destination key [key ...]
sdiffstore destination key [key ...]
(5)将集合中一个member移动到另一个集合
smove source destination member
命令示例
127.0.0.1:6379> sadd myset2 zhangsan xiaohao
(integer) 3
127.0.0.1:6379> smembers myset
1) "xiaohao"
2) "hao1"
3) "hao"
127.0.0.1:6379> sismember myset hao
(integer) 1
数据结构
set的内部编码有两种:
- intset(整数集合):当集合中的元素都是整数且元素个数小于set-max-intset-entries配置(默认
512个)时,Redis会选用intset来作为集合的内部实现,从而减少内存的使用。
- hashtable(哈希表):当集合类型无法满足intset的条件时,Redis会使用hashtable作为集合的内
部实现。
127.0.0.1:6379> config get set-max-intset-entries
1) "set-max-intset-entries"
2) "10"
127.0.0.1:6379> sadd keyset222 1 2 3 4 5 6 7 8 9 10
(integer) 10
127.0.0.1:6379> object encoding keyset222
"intset"
127.0.0.1:6379> sadd keyset222 1 2 3 4 5 6 7 8 9 12
(integer) 1
127.0.0.1:6379> object encoding keyset222
"hashtable"
127.0.0.1:6379> sadd keyset333 a
(integer) 1
127.0.0.1:6379> object encoding keyset333
"hashtable"
应用场景
标签(tag),给用户添加标签,或者用户给消息添加标签,这样有同一标签或者类似标签的可以给推 荐关注的事或者关注的人。
独立ip
点赞,或点踩,收藏等,可以放到set中实现
共同(好友)利用set的交集
三、zset (有序集合)¶
简介
1、Redis有序集合zset与普通集合set非常相似,是一个没有重复元素的字符串集合。
2、有序集合的每个成员都关联了一个评分(score),这个评分(score)被用来按照从最低分到最高分的方式排序集合中的成员。集合的成员是唯一的,但是评分可以重复。
3、元素有序,根据评分(score)或者次序(position)来获取一个范围的元素。
4、访问有序集合的中间元素也是非常快的,因此你能够使用有序集合作为一个没有重复成员的智能列表。
列表、集合、有序索引三者的异同点:

常用命令
集合内操作
(1)添加成员
zadd key score member [score member ...]
zincrby key increment member #增加成员的分数
(2)计算成员个数
zcard key
(3)计算某个成员的分数
zscore key member
(4)计算成员的排名
zrank key member #从分数从低到高返回排名,
zrevrank key member #zrevrank从分数从高到低返回排名
(5)返回指定排名范围的成员
zrange key start end [withscores] #从低到高
zrevrange key start end [withscores] #从高到低
(6)返回指定分数范围的成员
zrangebyscore key min max [withscores] [limit offset count] #从低到高
zrevrangebyscore key max min [withscores] [limit offset count] #从高到低
说明:min和max还支持开区间(小括号)和闭区间(中括号),-inf和 +inf分别代表无限小和无限大。
(7)返回指定分数范围成员个数
zcount key min max
(8)删除成员
zrem key member [member ...]
(9)删除指定排名内的升序元素
zremrangebyrank key start end
(10)删除指定分数范围的成员
zremrangebyscore key min max
集合间的操作
(1)交集
zinterstore destination numkeys key [key ...] [weights weight [weight ...]] [aggregate sum|min|max]
-
destination:交集计算结果保存到这个键。
-
numkeys:需要做交集计算键的个数。
-
key[key...]:需要做交集计算的键
-
weights weight[weight...]:每个键的权重,在做交集计算时,每个键中的每个member会将自己分数乘以这个权重,每个键的权重默认是1。
-
aggregate sum|min|max:计算成员交集后,分值可以按照sum(和)、min(最小值)、max(最大值)做汇总,默认值是sum。
127.0.0.1:6379> zinterstore user:1_inter_2 2 user:1 user:2
(integer) 3
(2)并集
zunionstore destination numkeys key [key ...] [weights weight [weight ...]] [aggregate sum|min|max]
127.0.0.1:6379> zunionstore user:1_union_2 2 user:1 user:2
(integer) 7
命令使用
127.0.0.1:6379> zadd myscoreset 100 hao 90 xiaohao
(integer) 2
127.0.0.1:6379> ZRANGE myscoreset 0 -1
1) "xiaohao"
2) "hao"
127.0.0.1:6379> ZSCORE myscoreset hao
"100"
数据结构
zset有内部编码有两种:
-
ziplist(压缩列表)
-
skiplist(跳跃表)
插入数据的逻辑
-
如果第一次为空,根据元素的个数创建zset的数据结构,默认是创建ziplist
-
随着元素的增多,达到配置的阈值,会将数据结构转为skiplist

应用场景
-
排行榜
-
社交网络
-
队列