您的位置:首页 > 数据库 > Redis

redis中list列表操作(二)

2019-05-10 17:35 176 查看
版权声明:如需转载,请写明出处 https://blog.csdn.net/weixin_43113679/article/details/90080933

在Redis中,List类型是按照插入顺序排序的字符串链表。和数据结构中的普通链表一样,我们可以在其头部(left)和尾部(right)添加新的元素。在插入时,如果该键并不存在,Redis将为该键创建一个新的链表。与此相反,如果链表中所有的元素均被移除,那么该键也将会被从数据库中删除。List中可以包含的最大元素数量是4294967295。

命令示例:

1. LPUSH/LPUSHX/LRANGE:(从头部存/键值存在才存/从头部取值)

127.0.0.1:6379> del mykey
(integer) 1
//mykey键并不存在,该命令会创建该键及与其关联的List,之后在将参数中的values从左到右依次插入,可以当成像队列的链表
127.0.0.1:6379> lpush mykey a b c d
(integer) 4
//#取从位置0开始到位置2结束的3个元素
127.0.0.1:6379> lrange mykey 0 2
1) "d"
2) "c"
3) "b"
//取链表中的全部元素,其中0表示第一个元素,-1表示最后一个元素
127.0.0.1:6379> lrange mykey 0 -1
1) "d"
2) "c"
3) "b"
4) "a"
//这里要记住,只能用lrange ,不能用rrange ,因为不存在这个命令
//mykey2键此时并不存在,因此该命令将不会进行任何操作,其返回值为0
127.0.0.1:6379> lpushx mykey2 e
(integer) 0
//可以看到mykey2没有关联任何List Value
127.0.0.1:6379> lrange mykey2 0 -1
(empty list or set)
//mykey键此时已经存在,所以该命令插入成功,并返回链表中当前元素的数量
127.0.0.1:6379> lpushx mykey e
(integer) 5
//获取该键的List Value的头部元素
127.0.0.1:6379> lrange mykey 0 0
1) "e"

2. LPOP/LLEN:(从头部弹/求长度)

127.0.0.1:6379> lpush mykey a b c d
(integer) 4
127.0.0.1:6379> lpop mykey  //弹出左边头部的value,这个环节像队列
"d"
127.0.0.1:6379> lpop mykey
"c"
127.0.0.1:6379> llen mykey   //返回此时链表的长度,因为已经弹出两次,所以长度还剩2
(integer) 2

3. LREM/LSET/LINDEX/LTRIM:(移除指定个数值为指定值的元素/设置指定位置为新值/查找元素位置/截取指定位置元素)

127.0.0.1:6379> del mykey
(integer) 1
127.0.0.1:6379> lpush mykey a b c d a c   //准备测试用例
(integer) 6
127.0.0.1:6379> lrem mykey 2 a   //从头部left向尾部right变量链表,删除2个值等于a的元素,返回实际删除的数量
(integer) 2
127.0.0.1:6379> lrange mykey 0 -1 //查看删除后的全部元素
1) "c"
2) "d"
3) "c"
4) "b"
127.0.0.1:6379> lindex mykey 1  //查看索引为1的元素值
"d"
127.0.0.1:6379> lset mykey 1 e  //将索引为1的元素值设置为新值
OK
127.0.0.1:6379> lindex mykey 1 //查看设置是否成功
"e"
127.0.0.1:6379> lindex mykey 6  //索引值6超过链表的元素的数量,该命令返回nil
(nil)
127.0.0.1:6379> lset mykey 6 hh  //索引值6超过链表的元素的数量,设置失败,返回错误信息
(error) ERR index out of range
127.0.0.1:6379> ltrim mykey 0 2  //仅保留索引值0到2之间的3个元素,注意第0个和第2个均被保留
OK
127.0.0.1:6379> lrange mykey 0 -1 //查看trim后的结果
1) "c"
2) "e"
3) "c"

练到这,有点疑惑又有点悟,所以画了一张图让自己理解更深

记住,没有rindex,只有lindex
4. LINSERT:(指定元素前面插入元素)

127.0.0.1:6379> del mykey  //清空
(integer) 1
127.0.0.1:6379> lpush mykey a b c f e  //准备测试数据
(integer) 5
127.0.0.1:6379> linsert mykey before a a1 //在a之前添加a1,搞清楚a1添加在a的左边还是右边,不懂的看看上面的图
(integer) 6
127.0.0.1:6379> lrange mykey 0 -1  //查看添加后的数据
1) "e"
2) "f"
3) "c"
4) "b"
5) "a1"
6) "a"
127.0.0.1:6379> linsert mykey after e e2   //在e之前添加e2
(integer) 7
127.0.0.1:6379> lrange mykey 0 -1
1) "e"
2) "e2"
3) "f"
4) "c"
5) "b"
6) "a1"
7) "a"
127.0.0.1:6379> linsert mykey after k a   //当往不存的的数据的前或后添加数据时返回-1,添加失败
(integer) -1
127.0.0.1:6379> linsert mykey5 after a a2 //当为不存在的key插入新元素时,该命令失败,返回0
(integer) 0

5. RPUSH/RPUSHX/RPOP/RPOPLPUSH:(从尾部插入/键值存在才插入/从尾部弹/从尾部弹出添加到头部)

127.0.0.1:6379> del mykey
(integer) 1
127.0.0.1:6379> rpush mykey a b c d
(integer) 4
127.0.0.1:6379> lrange mykey 0 -1 //这个如果思路混乱可以继续看上面的图进行比较
1) "a"
2) "b"
3) "c"
4) "d"
127.0.0.1:6379> rpushx mykey e  //当myke存在时才能把e添加到链表的尾部
(integer) 5
127.0.0.1:6379> lindex mykey 4
"e"
127.0.0.1:6379> rpushx mykey2 e  //不存在就返回0,表示失败
(integer) 0
127.0.0.1:6379> lrange mykey 0 -1  //在执行rpoplpush命令前,先看一下mykey中链表的元素有哪些,注意他们的位置关系
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
127.0.0.1:6379> rpoplpush mykey mykey2  //将mykey的尾部(如果是lpop就是头部了)元素e弹出,同时再插入到mykey2的头部(原子性的完成这两步操作)。
"e"
127.0.0.1:6379> lrange mykey 0 -1  //通过lrange命令查看mykey在弹出尾部元素后的结果。
1) "a"
2) "b"
3) "c"
4) "d"
127.0.0.1:6379> lrange mykey2 0 -1
1) "e"
127.0.0.1:6379> rpoplpush mykey mykey //将mykey的右边(尾部)第一个弹出,移动到mykey的左边(头部)第一个
"d"
127.0.0.1:6379> lrange mykey 0 -1 //查看移动结果
1) "d"
2) "a"
3) "b"
4) "c"

记住L开头就是左边,R开头就右边,这样就可以分清头部(左边)和尾部(右边)了
rpoplpush的问题
关于这个我想应该不会因为想省略一行代码而专门设置的这个命令吧,那也太扯了,看了我前一篇推荐的博客,原来是如果这样做可以不用担心业务数据丢失或者业务状态的不一致现象的发生,通过rpoplpush命令,可以先取出消息后再将它插入到备份队列中,直到完成正常的处理逻辑后再将该消息从备份队列中删除,同时提供一个守护进程,当发现备份队列消息到期后,让它重新回到主消息队列(这时说明处理逻辑出现了问题),让其他的程序处理
既然有rpoplpush,那有lpoprpush,rpoprpush,lpoplpush吗?
答案是没有,所以在设计的时候注意一下这一点

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: