加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

NoSQL----Redis 2.4--List

发布时间:2020-12-13 13:39:09 所属栏目:百科 来源:网络整理
导读:一、概述: List: 允许出现重复的元素,list可以作为栈(先进后出)或者队列(先进先出)。 头元素和尾元素: 头元素指的是列表左端/前端第一个元素;尾元素指的是列表右端/后端第一个元素。 举个例子,列表list包含三个元素:x,y,z,其中x是头元素,而z则

一、概述:

List:允许出现重复的元素,list可以作为栈(先进后出)或者队列(先进先出)。

头元素和尾元素:头元素指的是列表左端/前端第一个元素;尾元素指的是列表右端/后端第一个元素。

举个例子,列表list包含三个元素:x,y,z,其中x是头元素,而z则是尾元素。

空列表:指不包含任何元素的列表,Redis将不存在的key也视为空列表。

二、链表结构的小技巧:

针对链表结构的Value,Redis在其官方文档中给出了一些实用技巧,如RPOPLPUSH命令,下面给出具体的解释。

Redis链表经常会被用于消息队列的服务,以完成多程序之间的消息交换。假设一个应用程序正在执行LPUSH操作向链表中添加新的元素,我们通常将这样的程序称之为"生产者(Producer)",而另外一个应用程序正在执行RPOP操作从链表中取出元素,我们称这样的程序为"消费者(Consumer)"。如果此时,消费者程序在取出消息元素后立刻崩溃,由于该消息已经被取出且没有被正常处理,那么我们就可以认为该消息已经丢失,由此可能会导致业务数据丢失,或业务状态的不一致等现象的发生。然而通过使用RPOPLPUSH命令,消费者程序在从主消息队列中取出消息之后再将其插入到备份队列中,直到消费者程序完成正常的处理逻辑后再将该消息从备份队列中删除。同时我们还可以提供一个守护进程,当发现备份队列中的消息过期时,可以重新将其再放回到主消息队列中,以便其它的消费者程序继续处理。


三、方法:

1、lpush(left push)方法:


LPUSH key value [value ...]

将一个或多个值value插入到列表key的表头。

如果有多个value值,那么各个value值按从左到右的顺序依次插入到表头:比如对一个空列表(mylist)执行LPUSH mylist a b c,则结果列表为c b a,

等同于执行命令

LPUSH mylist a

LPUSH mylist b

LPUSH mylist c

如果key不存在,一个空列表会被创建并执行LPUSH操作。

当key存在但不是列表类型时,返回一个错误。


例如:
#加入单个元素

redis>LPUSHlanguagespython
(integer)1

#加入重复元素

redis>LPUSHlanguagespython
(integer)2

redis>LRANGElanguages0-1#列表允许重复元素
1)"python"
2)"python"

#加入多个元素

redis>LPUSHmylistabc
(integer)3

redis>LRANGEmylist0-1
1)"c"
2)"b"
3)"a"

2、lpushx(left pushx)方法:

LPUSHX key value

将值value插入到列表key的表头,当且仅当key存在并且是一个列表。

和LPUSH命令相反,当key不存在时,LPUSHX命令什么也不做。

例如:
#情况1:对空列表执行LPUSHX

redis>LLENgreet#greet是一个空列表
(integer)0

redis>LPUSHXgreet"hello"#尝试LPUSHX,失败,因为列表为空
(integer)0


#情况2:对非空列表执行LPUSHX

redis>LPUSHgreet"hello"#先用LPUSH创建一个有一个元素的列表
(integer)1

redis>LPUSHXgreet"goodmorning"#这次LPUSHX执行成功
(integer)2

redis>LRANGEgreet0-1
1)"goodmorning"
2)"hello"

3、rpush(rightpush)方法:

RPUSH key value [value ...]

将一个或多个值value插入到列表key的表尾。

如果有多个value值,那么各个value值按从左到右的顺序依次插入到表尾:

比如对一个空列表(mylist)执行RPUSH mylist a b c,则结果列表为a b c,

等同于执行命令

RPUSH mylist a、

RPUSH mylist b、

RPUSH mylist c。

如果key不存在,一个空列表会被创建并执行RPUSH操作。

当key存在但不是列表类型时,返回一个错误。


备注:在Redis 2.4版本以前的RPUSH命令,都只接受单个value值。

#添加单个元素

redis>RPUSHlanguagesc
(integer)1

#添加重复元素

redis>RPUSHlanguagesc
(integer)2

redis>LRANGElanguages0-1#列表允许重复元素
1)"c"
2)"c"

#添加多个元素

redis>RPUSHmylistabc
(integer)3

redis>LRANGEmylist0-1
1)"a"
2)"b"
3)"c"

4、rpushx(rightpushx)方法:

RPUSHX key value

将值value插入到列表key的表尾,当且仅当key存在并且是一个列表。

和RPUSH命令相反,当key不存在时,RPUSHX命令什么也不做。


例如:
#情况1:key不存在

redis>LLENgreet
(integer)0

redis>RPUSHXgreet"hello"#对不存在的key进行RPUSHX,PUSH失败。
(integer)0


#情况2:key存在且是一个非空列表

redis>RPUSHgreet"hi"#先用RPUSH插入一个元素
(integer)1

redis>RPUSHXgreet"hello"#greet现在是一个列表类型,RPUSHX操作成功。
(integer)2

redis>LRANGEgreet0-1
1)"hi"
2)"hello"

5、lpop(leftpop)方法:

LPOP key

移除并返回列表key的头元素。

redis>LLENcourse
(integer)0

redis>RPUSHcoursealgorithm001
(integer)1
redis>RPUSHcoursec++101
(integer)2

redis>LPOPcourse#移除头元素
"algorithm001"

6、rpop(rightpop)方法:

RPOP key

移除并返回列表key的尾元素。

redis>RPUSHmylist"one"
(integer)1
redis>RPUSHmylist"two"
(integer)2
redis>RPUSHmylist"three"
(integer)3

redis>RPOPmylist#返回被弹出的元素
"three"

redis>LRANGEmylist0-1#列表剩下的元素
1)"one"
2)"two"

7、llen方法:

LLEN key

返回列表key的长度。

如果key不存在,则key被解释为一个空列表,返回0.

如果key不是列表类型,返回一个错误。

#情况1:空列表

redis>LLENjob
(integer)0

#情况2:非空列表
redis>LPUSHjob"cookfood"
(integer)1
redis>LPUSHjob"havelunch"
(integer)2

redis>LLENjob
(integer)2

8、lrange方法:

LRANGE key start end

返回列表key中指定区间内的元素,区间以偏移量start和end指定。

下标(index)参数start和end都以0为底,也就是说,以0表示列表的第一个元素,以1表示列表的第二个元素,以此类推。

你也可以使用负数下标,以-1表示列表的最后一个元素,-2表示列表的倒数第二个元素,以此类推。

超出范围的下标

超出范围的下标值不会引起错误。

如果start下标比列表的最大下标end(LLENlist减去1)还要大,或者start>stop,LRANGE返回一个空列表。

stop下标比end下标还要大,Redis将stop的值设置为end


redis>RPUSHfp-languagelisp#插入一个值到列表fp-language
(integer)1
redis>LRANGEfp-language00
1)"lisp"

redis>RPUSHfp-languagescheme
(integer)2
redis>LRANGEfp-language01
1)"lisp"
2)"scheme"

9、linsert方法:


LINSERT key BEFORE|AFTER pivot value

将值value插入到列表key当中,位于值pivot之前或之后。

当pivot不存在于列表key时,不执行任何操作。

当key不存在时,key被视为空列表,不执行任何操作。

如果key不是列表类型,返回一个错误。

redis>RPUSHmylist"Hello"
(integer)1
redis>RPUSHmylist"World"
(integer)2

redis>LINSERTmylistBEFORE"World""There"
(integer)3

redis>LRANGEmylist0-1
1)"Hello"
2)"There"
3)"World"

redis>LINSERTmylistBEFORE"go""let's"#对一个非空列表插入,查找一个不存在的pivot
(integer)-1#失败

redis>EXISTSfake_list#对一个空列表执行LINSERT命令
(integer)0

redis>LINSERTfake_listBEFORE"nono""gogogog"
(integer)0#失败

10、lset方法:

LSET key index value

将列表key下标为index的元素的值替换为value。

更多信息请参考LINDEX操作。

当index参数超出范围,或对一个空列表(key不存在)进行LSET时,返回一个错误。


#情况1:对空列表(key不存在)进行LSET

redis>EXISTSlist
(integer)0

redis>LSETlist0item
(error)ERRnosuchkey


#情况2:对非空列表进行LSET

redis>LPUSHjob"cookfood"
(integer)1

redis>LRANGEjob00
1)"cookfood"

redis>LSETjob0"playgame"
OK

redis>LRANGEjob00
1)"playgame"


#情况3:index超出范围

redis>LLENlist#列表长度为1
(integer)1

redis>LSETlist3'outofrange'
(error)ERRindexoutofrange

11、lrem方法:

LREM key count value

根据参数count的值,移除列表中与参数value相等的元素。

count的值可以是以下几种:

count > 0: 从表头开始向表尾搜索,移除与value相等的元素,数量为count。

count < 0: 从表尾开始向表头搜索,移除与value相等的元素,数量为count的绝对值。

count = 0: 移除表中所有与value相等的值。

#先创建一个表,内容排列是
#morninghellomorninghelllomorning

redis>LPUSHgreet"morning"
(integer)1
redis>LPUSHgreet"hello"
(integer)2
redis>LPUSHgreet"morning"
(integer)3
redis>LPUSHgreet"hello"
(integer)4
redis>LPUSHgreet"morning"
(integer)5

redis>LRANGEgreet04#查看所有元素
1)"morning"
2)"hello"
3)"morning"
4)"hello"
5)"morning"

redis>LREMgreet2morning#移除从表头到表尾,最先发现的两个morning
(integer)2#两个元素被移除

redis>LLENgreet#还剩3个元素
(integer)3

redis>LRANGEgreet02
1)"hello"
2)"hello"
3)"morning"

redis>LREMgreet-1morning#移除从表尾到表头,第一个morning
(integer)1

redis>LLENgreet
(integer)2

redis>LRANGEgreet01
1)"hello"
2)"hello"

redis>LREMgreet0hello#移除表中所有hello
(integer)2#两个hello被移除

redis>LLENgreet
(integer)0

12、ltrim方法:

LTRIM key start stop

对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。

举个例子,执行命令LTRIM list 0 2,表示只保留列表list的前三个元素,其余元素全部删除。

下标(index)参数start和stop都以0为底,也就是说,以0表示列表的第一个元素,以1表示列表的第二个元素,以此类推。

你也可以使用负数下标,以-1表示列表的最后一个元素,-2表示列表的倒数第二个元素,以此类推。

当key不是列表类型时,返回一个错误。


#情况1:一般情况下标

redis>LRANGEalpha0-1#建立一个5元素的列表
1)"h"
2)"e"
3)"l"
4)"l"
5)"o"

redis>LTRIMalpha1-1#删除索引为0的元素
OK

redis>LRANGEalpha0-1#"h"被删除
1)"e"
2)"l"
3)"l"
4)"o"


#情况2:stop下标比元素的最大下标要大

redis>LTRIMalpha110086
OK
redis>LRANGEalpha0-1
1)"l"
2)"l"
3)"o"


#情况3:start和stop下标都比最大下标要大,且start<sotp

redis>LTRIMalpha10086200000
OK
redis>LRANGEalpha0-1#整个列表被清空,等同于DELalpha
(emptylistorset)


#情况4:start>stop

redis>LRANGEalpha0-1#在新建一个列表
1)"h"
2)"u"
3)"a"
4)"n"
5)"g"
6)"z"

redis>LTRIMalpha100864
OK

redis>LRANGEalpha0-1#列表同样被清空
(emptylistorset)

13、rpoplpush方法:


RPOPLPUSH source destination

命令RPOPLPUSH在一个原子时间内,执行以下两个动作:

将列表source中的最后一个元素(尾元素)弹出,并返回给客户端。

将source弹出的元素插入到列表destination,作为destination列表的的头元素。

举个例子,你有两个列表source和destination,source列表有元素a,b,c,destination列表有元素x,z,执行RPOPLPUSH source destination之后,source列表包含元素a,b,destination列表包含元素c,x,z ,并且元素c被返回。

如果source不存在,值nil被返回,并且不执行其他动作。

如果source和destination相同,则列表中的表尾元素被移动到表头,并返回该元素,可以把这种特殊情况视作列表的旋转(rotation)操作。


#相关数据

redis>RPUSHalphaa
(integer)1
redis>RPUSHalphab
(integer)2
redis>RPUSHalphac
(integer)3
redis>RPUSHalphad
(integer)4

#情况1:source和destination不同

redis>LRANGEalpha0-1#查看所有元素
1)"a"
2)"b"
3)"c"
4)"d"

redis>RPOPLPUSHalphareciver#执行一次RPOPLPUSH看看
"d"

redis>LRANGEalpha0-1
1)"a"
2)"b"
3)"c"

redis>LRANGEreciver0-1
1)"d"

redis>RPOPLPUSHalphareciver#再执行一次,确保rpop和lpush的位置正确
"c"

redis>LRANGEalpha0-1
1)"a"
2)"b"

redis>LRANGEreciver0-1
1)"c"
2)"d"


#情况2:source和destination相同

redis>RPOPLPUSHalphaalpha
"c"

redis>LRANGEalpha0-1#原来的尾元素"c"被放到了头部
1)"c"
2)"a"
3)"b"

14、lindex方法:

LINDEX key index

返回列表key中,下标为index的元素。

下标(index)参数start和stop都以0为底,也就是说,以0表示列表的第一个元素,以1表示列表的第二个元素,以此类推。

你也可以使用负数下标,以-1表示列表的最后一个元素,-2表示列表的倒数第二个元素,以此类推。

如果key不是列表类型,返回一个错误。

redis>LPUSHmylist"World"
(integer)1

redis>LPUSHmylist"Hello"
(integer)2

redis>LINDEXmylist0
"Hello"

redis>LINDEXmylist-1
"World"

redis>LINDEXmylist3#index不在mylist的区间范围内
(nil)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读