要说清楚列表数据类型,最好先讲一点儿理论背景,在信息技术界List这个词常常被使用不当。例如”Python Lists”就名不副实(名为Linked Lists),但他们实际上是数组(同样的数据类型在Ruby中叫数组) 一般意义上讲,列表就是有序元素的序列:10,20,1,2,3就是一个列表。但用数组实现的List和用Linked List实现的List,在属性方面大不相同。 Redis lists基于Linked Lists实现。这意味着即使在一个list中有数百万个元素,在头部或尾部添加一个元素的操作,其时间复杂度也是常数级别的。用LPUSH 命令在十个元素的list头部添加新元素,和在千万元素list头部添加新元素的速度相同。 那么,坏消息是什么?在数组实现的list中利用索引访问元素的速度极快,而同样的操作在linked list实现的list上没有那么快。 Redis Lists用linked list实现的原因是:对于数据库系统来说,至关重要的特性是:能非常快的在很大的列表上添加元素。另一个重要因素是,正如你将要看到的:Redis lists能在常数时间取得常数长度。 如果快速访问集合元素很重要,建议使用可排序集合(sorted sets)
指令列表列表 — Redis 命令参考
LPUSH RPUSH LRANGE
127.0.0.1:6379[1]> lpush names donghao
(integer) 1
127.0.0.1:6379[1]> lrange names 0 -1
1) "donghao"
127.0.0.1:6379[1]> rpush names ttt
(integer) 2
127.0.0.1:6379[1]> lpush names qqq
(integer) 3
127.0.0.1:6379[1]> lrange names 0 -1
1) "qqq"
2) "donghao"
3) "ttt"
127.0.0.1:6379[1]> lrange names 0 1
1) "qqq"
2) "donghao"
批量添加
127.0.0.1:6379[1]> rpush mylist 1 2 3 4 5 "foo bar"
(integer) 6
127.0.0.1:6379[1]> lrange mylist 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "foo bar"
rpop lpop
127.0.0.1:6379[1]> rpop mylist
"foo bar"
127.0.0.1:6379[1]> lpop mylist
"1"
127.0.0.1:6379[1]> lrange mylist 0 -1
1) "2"
2) "3"
3) "4"
4) "5"
5) "5"
127.0.0.1:6379[1]> rpop mylist 3 # 指定个数
1) "5"
2) "5"
3) "4"
127.0.0.1:6379[1]> rpop mylist1 # 没有元素返回空
(nil)
列表长度
127.0.0.1:6379[1]> llen mylist
(integer) 6
移除指定个数value
127.0.0.1:6379[1]> lrange mylist 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
5) "foo bar"
6) "1"
127.0.0.1:6379[1]> lrem mylist 2 1 # lrem mylist count value
(integer) 2
127.0.0.1:6379[1]> lrange mylist 0 -1
1) "2"
2) "3"
3) "4"
4) "foo bar"
截取
127.0.0.1:6379[1]> lrange mylist 0 -1
1) "2"
2) "3"
3) "4"
4) "foo bar"
127.0.0.1:6379[1]> LTRIM mylist 1 2
OK
127.0.0.1:6379[1]> lrange mylist 0 -1
1) "3"
2) "4"
pop值放到新List
127.0.0.1:6379[1]> rpoplpush mylist newlist
"4"
127.0.0.1:6379[1]> lrange newlist 0 -1
1) "4"
lset 将列表 key 下标为 index 的元素的值设置为 value 。
127.0.0.1:6379[1]> lrange list 0 -1
1) "1"
2) "item2"
127.0.0.1:6379[1]> lset list 1 666
OK
127.0.0.1:6379[1]> lrange list 0 -1
1) "1"
2) "666"
插值
127.0.0.1:6379[1]> LINSERT list after 1 999
(integer) 3
127.0.0.1:6379[1]> lrange list 0 -1
1) "1"
2) "999"
3) "666"
List上的阻塞操作 可以使用Redis来实现生产者和消费者模型,如使用LPUSH和RPOP来实现该功能。但会遇到这种情景:list是空,这时候消费者就需要轮询来获取数据,这样就会增加redis的访问压力、增加消费端的cpu时间,而很多访问都是无用的。为此redis提供了阻塞式访问 BRPOP 和 BLPOP 命令。 消费者可以在获取数据时指定如果数据不存在阻塞的时间,如果在时限内获得数据则立即返回,如果超时还没有数据则返回null, 0表示一直阻塞。 同时redis还会为所有阻塞的消费者以先后顺序排队(RPOPLPUSH 和 BRPOPLPUSH)