Redis学习笔记—数据类型:列表(list)

列表(list)类型是用来存储多个有序的字符串。列表是一种比较灵活的数据结构,它可以充当栈和队列的角色,在实际开发上有很多应用场景。

添加操作

1.从右边插入元素

rpush key value [value ...]

从右边插入a,b,c

127.0.0.1:6379> rpush mylist a b c
(integer) 3

从左到右获取列表所有元素

127.0.0.1:6379> lrange mylist 0 -1
1) "a"
2) "b"
3) "c"

2.从左边插入元素

lpush key value [value ...]

从左边插入d,e

127.0.0.1:6379> lpush mylist d e
(integer) 5
127.0.0.1:6379> lrange mylist 0 -1
1) "e"
2) "d"
3) "a"
4) "b"
5) "c"

3.向某个元素前或者后插入元素

linsert key BEFORE|AFTER pivot value

在key为mylist的数组元素“e”之后添加一个“test”元素,在元素“b”之前添加一个“test2”元素

127.0.0.1:6379> linsert mylist after e test
(integer) 6
127.0.0.1:6379> lrange mylist 0 -1
1) "e"
2) "test"
3) "d"
4) "a"
5) "b"
6) "c"
127.0.0.1:6379> linsert mylist before b test2
(integer) 7
127.0.0.1:6379> lrange mylist 0 -1
1) "e"
2) "test"
3) "d"
4) "a"
5) "test2"
6) "b"
7) "c"

查找操作

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

lrange key start stop

第一,索引下标从左到右分别是0到N-1,但是从右到左分别是-1到-N。
第二,lrange中的end选项包含了自身,这个和很多编程语言不包含end不太相同

获取key为mylist的索引位置3-5(即第四个到第六个)的列表数据;索引位置倒数第四个-4到最后一个-1的列表数据

127.0.0.1:6379> lrange mylist 3 5
1) "a"
2) "test2"
3) "b"
127.0.0.1:6379> lrange mylist -4 -1
1) "a"
2) "test2"
3) "b"
4) "c"

2.获取指定索引下标的元素

lindex key index

获取key为mylist索引位置为3(第四个)的元素

127.0.0.1:6379> lrange mylist 0 -1
1) "e"
2) "test"
3) "d"
4) "a"
5) "test2"
6) "b"
7) "c"
127.0.0.1:6379> lindex mylist 3
"a"

3.获取列表长度

llen key

获取key为mylist的列表长度

127.0.0.1:6379> llen mylist
(integer) 7

删除操作

1.从列表左边弹出元素

lpop key

删除key为mylist的左边第一个元素

127.0.0.1:6379> lrange mylist 0 -1
1) "e"
2) "test"
3) "d"
4) "a"
5) "test2"
6) "b"
7) "c"
127.0.0.1:6379> lpop mylist
"e"
127.0.0.1:6379> lrange mylist 0 -1
1) "test"
2) "d"
3) "a"
4) "test2"
5) "b"
6) "c"

2.从列表右边弹出元素

rpop key

3.删除指定元素

lrem key count value

lrem命令会从列表中找到等于value的元素进行删除,根据count的不同分为三种情况:

  • count>0,从左到右,删除最多count个元素。
  • count<0,从右到左,删除最多count绝对值个元素。
  • count=0,删除所有。

先给key为mylist的列表左边添加5个“a”元素,然后删除五个“a”元素

127.0.0.1:6379> lpush mylist a a a a a 
(integer) 11
127.0.0.1:6379> lrange mylist 0 -1
1) "a"
2) "a"
3) "a"
4) "a"
5) "a"
6) "e"
7) "test"
8) "d"
9) "test2"
10) "b"
11) "c"
127.0.0.1:6379> lrem mylist 5 a
(integer) 5
127.0.0.1:6379> lrange mylist 0 -1
1) "e"
2) "test"
3) "d"
4) "test2"
5) "b"
6) "c"

4.按照索引范围修剪列表

ltirm key start end

保留key为mylist的列表索引位置2~4(第三个到第五个)的元素

127.0.0.1:6379> lrange mylist 0 -1
1) "e"
2) "test"
3) "d"
4) "test2"
5) "b"
6) "c"
127.0.0.1:6379> ltrim mylist 2 4
OK
127.0.0.1:6379> lrange mylist 0 -1
1) "d"
2) "test2"
3) "b"

修改操作

lset key index value

修改key为mylist索引位置1(第二个)的元素值

127.0.0.1:6379> lrange mylist 0 -1
1) "d"
2) "test2"
3) "b"
127.0.0.1:6379> lset mylist 1 test
OK
127.0.0.1:6379> lrange mylist 0 -1
1) "d"
2) "test"
3) "b"

阻塞删除操作

blpop key [key ...] timeout
brpop key [key ...] timeout

1.列表为空

如果查询列表为空,则等待timeout设置的时间返回,比如timeout=5,就是等待5秒后返回;如果timeout=0就会一直阻塞下去,直到给此未设置的列表key添加元素

127.0.0.1:6379> blpop listkey 5
(nil)
(5.03s)
127.0.0.1:6379> blpop listkey 0
处于阻塞状态

打开另外的客户端,给空key为listkey的添加列表元素

127.0.0.1:6379> lpush listkey a
(integer) 1

此时一直处于阻塞的客户端返回删除的列表key和删除的元素

127.0.0.1:6379> blpop listkey 0
1) "listkey"
2) "a"
(68.04s)

 2.列表不为空

列表不为空如果timeout=0会立即返回删除的列表key和删除的元素,如果设置了时间会等到时间到了返回删除结果

127.0.0.1:6379> blpop mylist 0
1) "mylist"
2) "a"

第一点,如果是多个键,那么brpop会从左至右遍历键,一旦有一个键能删除元素,客户端立即返回
第二点,如果多个客户端对同一个键执行brpop,那么最先执行brpop命令的客户端可以获取到弹出的值

内部编码

列表类型的内部编码有两种。

  • ziplist(压缩列表):当列表的元素个数小于list-max-ziplist-entries配置(默认512个),同时列表中每个元素的值都小于list-max-ziplist-value配置时(默认64字节),Redis会选用ziplist来作为列表的内部实现来减少内存的使用。
  • linkedlist(链表):当列表类型无法满足ziplist的条件时,Redis会使用linkedlist作为列表的内部实现。
  • quicklist内部编码,简单地说它是以一个ziplist为节点的linkedlist,它结合了ziplist和linkedlist两者的优势,为列表类型提供了一种更为优秀的内部编码实

使用场景

  • lpush+lpop=Stack(栈)
  • lpush+rpop=Queue(队列)
  • lpsh+ltrim=Capped Collection(有限集合)
  • lpush+brpop=Message Queue(消息队列)

1.消息队列

Redis的lpush+brpop命令组合即可实现阻塞队列,生产者客户端使用lrpush从列表左侧插入元素,多个消费者客户端使用brpop命令阻塞式的“抢”列表尾部的元素,多个客户端保证了消费的负载均衡和高可用性。

2.文章列表

每个用户有属于自己的文章列表,现需要分页展示文章列表。此时可以考虑使用列表,因为列表不但是有序的,同时支持按照索引范围获取元素。

发表评论

邮箱地址不会被公开。 必填项已用*标注