Redis Lists
key是字符串,value是一个有序的list。特点是有序、可以重复。
要说清楚列表数据类型,最好先讲一点儿理论背景,在信息技术界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)。可排序集合我们会随后介绍。
rpush key v1 v2 v3 …vn | 从列表右端插入值 |
linsert key before | after value newValue |
lpop key | 从左弹出一个item |
lrem key count value | 根据count的值,从列表中删除所有value相等的项:count>0,从左到右,删除最多count个value相等的值count<0,从右到左,删除最多Math.abs(count)个v相等的值,count=0, 删除所有v相等的项 |
lrim key start end | 按照索引范围修剪列表 |
lrange key start end | 获取列表指定索引范围所有item |
lset key index newValue | 设置列表指定索引值为newV o(n) |
blpop | b代表阻塞的概念。 blpop key timeout 是lpop的阻塞版本,timeout是阻塞超时时间,timeout=0为永远不阻塞。 |
brpop | 跟blpop一样,只不过从右边获取 |
LPUSH 命令可向list的左边(头部)添加一个新元素,而RPUSH命令可向list的右边(尾部)添加一个新元素。最后LRANGE 命令可从list中取出一定范围的元素:
> rpush mylist A
(integer) 1
> rpush mylist B
(integer) 2
> lpush mylist first
(integer) 3
> lrange mylist 0 -1
1) "first"
2) "A"
3) "B"
注意:LRANGE 带有两个索引,一定范围的第一个和最后一个元素。这两个索引都可以为负来告知Redis从尾部开始计数,因此-1表示最后一个元素,-2表示list中的倒数第二个元素,以此类推。
上面的所有命令的参数都可变,方便你一次向list存入多个值。
> rpush mylist 1 2 3 4 5 "foo bar"
(integer) 9
> lrange mylist 0 -1
1) "first"
2) "A"
3) "B"
4) "1"
5) "2"
6) "3"
7) "4"
8) "5"
9) "foo bar"
还有一个重要的命令是pop,它从list中删除元素并同时返回删除的值。可以在左边或右边操作。
> rpush mylist a b c
(integer) 3
> rpop mylist
"c"
> rpop mylist
"b"
> rpop mylist
"a"
我们增加了三个元素,并弹出了三个元素,因此,在这最后 列表中的命令序列是空的,没有更多的元素可以被弹出。如果我们尝试弹出另一个元素,这是我们得到的结果:
> rpop mylist
(nil)
当list没有元素时,Redis 返回了一个NULL。
可以使用LTRIM把list从左边截取指定长度。
> rpush mylist 1 2 3 4 5
(integer) 5
> ltrim mylist 0 2
OK
> lrange mylist 0 -1
1) "1"
2) "2"
3) "3"
blpop(blpop key timeout): 从列表左端移出并获取列表第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。(lpop阻塞版本,timeout是阻塞超时时间,timeout = 0表示永不阻塞) 时间复杂度O(1)
brpop(brpop key timeout): 从列表右端移出并获取列表第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。(lpop阻塞版本,timeout是阻塞超时时间,timeout = 0表示永不阻塞) 时间复杂度O(1)
总结:
①:lpush + lpop = Stack(实现栈)
②:lpush + rpop = Queue(实现队列)
③:lpush + ltrim = Capped Collection(实现固定集合)
④:lpush + brpop = Message Queue(实现消息队列)
应用场景:
Redis list的应用场景非常多,也是Redis最重要的数据结构之一,比如twitter的关注列表,粉丝列表等都可以用Redis的list结构来实现。
Lists 就是链表,相信略有数据结构知识的人都应该能理解其结构。使用Lists结构,我们可以轻松地实现最新消息排行等功能。Lists的另一个应用就是消息队列,
可以利用Lists的PUSH操作,将任务存在Lists中,然后工作线程再用POP操作将任务取出进行执行。Redis还提供了操作Lists中某一段的api,你可以直接查询,删除Lists中某一段的元素。