1 简介
list是一个链表结构,主要功能是push、pop、获取一个范围的所有值等等。操作中key理解为链表的名字。
使用 list 结构,我们可以轻松地实现最新消息排行等功能(比如新浪微博的 TimeLine )。list 的另一个应用就是消息队列,可以利用 list 的 push操作,将任务存在 list 中,然后工作线程再用pop操作将任务取出进行执行
2 应用场景
消息队列系统
比如sina微博:在redis中我们的最新微博ID使用了常驻缓存,这是一直更新的。
但是做了限制不能超过5000个ID,因此获取ID的函数会一直询问redis。
系统不会像传统方式那样“刷新”缓存,redis实例中的信息永远是一致的。
SQL数据库(或是硬盘上的其他类型数据)只是在用户需要获取“很远”的数据时才会被触发,而主页或第一个评论页是不会麻烦到硬盘上的数据库了。
3 增
#将一个值或者多个值插入列表的表头(若key不存在,则添加key并依次添加)
127.0.0.1:6379> lpush list one
(integer) 1
127.0.0.1:6379> lpush list two
(integer) 2
127.0.0.1:6379> lpush list three
(integer) 3
127.0.0.1:6379> lpush list "yanzhijun longxiangjun weixiongjun fengziying"
(integer) 4
127.0.0.1:6379> lpush list "1 2 3 4 5"
(integer) 5
127.0.0.1:6379> lrange list 0 -1
1) "1 2 3 4 5"
2) "yanzhijun longxiangjun weixiongjun fengziying"
3) "three"
4) "two"
5) "one"
# 在尾部添加key,右侧
127.0.0.1:6379> rpush list right
(integer) 6
127.0.0.1:6379> lrange list 0 -1
1) "1 2 3 4 5"
2) "yanzhijun longxiangjun weixiongjun fengziying"
3) "three"
4) "two"
5) "one"
6) "right"
127.0.0.1:6379>
# 一行添加
127.0.0.1:6379> lpush beiliangjun yanzhijun longxiangjun weixiongjun fengziying
(integer) 4
127.0.0.1:6379> lrange beiliangjun 0 -1
1) "fengziying"
2) "weixiongjun"
3) "longxiangjun"
4) "yanzhijun"
# 追加一个value值,若key不存在,LPUSHX什么都不做
127.0.0.1:6379> lpushx beiliang xujiajun
(integer) 0
127.0.0.1:6379>
linsert 将某个具体的 value 插入到列表中某个元素的前面或后面
127.0.0.1:6379> lpush mylist hello
(integer) 1
127.0.0.1:6379> lpush mylist world
(integer) 2
127.0.0.1:6379> linsert mylist before "world" "other" # 在 world 前面插入 other
(integer) 3
127.0.0.1:6379> lrange mylist 0 -1
1) "other"
2) "world"
3) "hello"
127.0.0.1:6379> linsert mylist after "world" "china" # 在 world 后面插入 china
(integer) 4
127.0.0.1:6379> lrange mylist 0 -1
1) "other"
2) "world"
3) "china"
4) "hello"
127.0.0.1:6379>
4 删
从头部开始找,按先后顺序,值为 three 的元素,删除数量为 3 个,若存在第 4 个,则不删除
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "three"
3) "two"
4) "one"
5) "1 2 3 4 5"
6) "yanzhijun longxiangjun weixiongjun fengziying"
7) "three"
8) "two"
9) "one"
127.0.0.1:6379> lrem list 3 three
(integer) 3
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"
3) "1 2 3 4 5"
4) "yanzhijun longxiangjun weixiongjun fengziying"
5) "two"
6) "one"
127.0.0.1:6379>
从头开始,索引为 0,1,2 的 3 个元素,其余全部删除
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"
3) "1 2 3 4 5"
4) "yanzhijun longxiangjun weixiongjun fengziying"
5) "two"
6) "one"
127.0.0.1:6379> ltrim list 0 2 # 通过下标截取指定的长度,这个 list 已经被改变了
OK
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"
3) "1 2 3 4 5"
127.0.0.1:6379>
删除key
127.0.0.1:6379> del list
(integer) 1
127.0.0.1:6379> lrange list 0 -1
(empty array)
127.0.0.1:6379>
5 改
lset 修改列表中指定下标的值,要求:列表和下标必须存在
127.0.0.1:6379> exists list # 判断列表是否存在
(integer) 0
127.0.0.1:6379> lset list 0 handaoxing # 列表不存在更新就会报错
(error) ERR no such key
127.0.0.1:6379>
127.0.0.1:6379> lpush list value1
(integer) 1
127.0.0.1:6379> lrange list 0 0 # 获取第一个元素的值
1) "value1"
127.0.0.1:6379> lset list 0 xuezhong # 如果存在,更新当前下标的值
OK
127.0.0.1:6379> lrange list 0 0
1) "xuezhong"
127.0.0.1:6379> lset list 1 handaoxing # 若索引不存在,即索引越界,则返回错误信息
(error) ERR index out of range
127.0.0.1:6379>
rpoplpush 移动列表的最后一个元素,将它移动到新的列表中
127.0.0.1:6379> rpush mylist one
(integer) 1
127.0.0.1:6379> rpush mylist two
(integer) 2
127.0.0.1:6379> rpush mylist three
(integer) 3
127.0.0.1:6379> lrange mylist 0 -1
1) "one"
2) "two"
3) "three"
127.0.0.1:6379> rpoplpush mylist myotherlist # 弹出列表的最后一个元素,将它插入到新的列表中
"three"
127.0.0.1:6379> lrange mylist 0 -1 # 查看原来的列表
1) "one"
2) "two"
127.0.0.1:6379> lrange myotherlist 0 -1 # 查看目标列表中,确实存在该值了
1) "three"
127.0.0.1:6379>
6 查
读取整个list
127.0.0.1:6379> lrange list 0 -1
1) "1 2 3 4 5"
2) "yanzhijun longxiangjun weixiongjun fengziying"
3) "three"
4) "two"
5) "one"
范围查询索引
127.0.0.1:6379> lrange list 0 1
1) "1 2 3 4 5"
2) "yanzhijun longxiangjun weixiongjun fengziying"
127.0.0.1:6379>
查询索引(头部开始)
127.0.0.1:6379> lindex list 0
"1 2 3 4 5"
查询索引(尾部第一个)
127.0.0.1:6379> lindex list -1
"one"
127.0.0.1:6379>
查看一个列表内有多少行
127.0.0.1:6379> llen list
(integer) 5
127.0.0.1:6379>
列表头部弹出,弹一行少一行,从左侧取出第一个元素
127.0.0.1:6379> lpop list
"1 2 3 4 5"
127.0.0.1:6379> lpop list
"yanzhijun longxiangjun weixiongjun fengziying"
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
3) "one"
127.0.0.1:6379>
列表尾部,从右侧取出第一个元素
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> rpop list
"one"
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
127.0.0.1:6379>
微博、微信(wechat)朋友圈场景实现:
#发朋友圈
127.0.0.1:6379> LPUSH wechat "monday,i love wuxia"
(integer) 1
127.0.0.1:6379> LPUSH wechat "Tuesday,i love xianxia"
(integer) 2
127.0.0.1:6379> LPUSH wechat "Wednesday,i love dushi"
(integer) 3
#查看朋友圈内容
127.0.0.1:6379> LRANGE wechat 0 -1
1) "Wednesday,i love xianxia"
2) "Tuesday,i love xianxia"
3) "monday,i love xianxia"
7 总结
- 它实际上是一个链表,before Node after,left,right 都可以插入值
- 如果 key 不存在,创建新的链表
- 如果 key 存在,新增内容
- 如果移除了所有值,空链表,也代表不存在
- 在两边插入或者改动值,效率最高,中间元素,相对来说效率会低一些