一、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 #只保留列表listkey2个到第4个元素
OK

(4)阻塞式的删除操作

blpop/brpop key [key ...] timeout

查询

(1)获取指定范围内的元素列表

lrange key start end #左-》右:0N-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

应用场景

  • 排行榜

  • 社交网络

  • 队列