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