列表類型
list可以存儲(chǔ)一個(gè)有序的字符串列表捶闸,一般用于在兩端添加元素胯府,并從兩端獲取數(shù)據(jù),或獲取列表中一個(gè)片段數(shù)據(jù)列。Redis使用雙向鏈表實(shí)現(xiàn)列表脚翘,因此兩端添加元素時(shí)間復(fù)雜度為O(1)灼卢,因此兩端添加元素性能較好;獲取時(shí)来农,越接近兩端的元素獲取速度就越快鞋真。(因此獲取兩端有限長(zhǎng)度的子列表,如獲取首尾的10條記錄沃于,從一個(gè)千萬(wàn)級(jí)和一個(gè)百位級(jí)的列表獲取速度是一樣的)涩咖。
因?yàn)椴捎昧穗p向鏈表實(shí)現(xiàn),雖然首尾添加和讀取數(shù)據(jù)很快繁莹,但是要根據(jù)索引查找一個(gè)元素性能較慢檩互。和java的LinkedList
類似,查找元素時(shí)咨演,如查找一個(gè)確切位置123
闸昨,則列表需要移動(dòng)指針到指定位置,并讀取數(shù)據(jù)薄风,因此位置離頭尾越遠(yuǎn)饵较,則查找過程時(shí)間越長(zhǎng),相對(duì)應(yīng)的性能越低村刨,這里的例子時(shí)間復(fù)雜度為O(123)告抄,如果長(zhǎng)度為n
的列表,從一端查找元素嵌牺,則最差為O(n)
打洼。
列表類型最多可容納2^32-1
個(gè)元素。列表的值類型必須是字符串逆粹,不能再嵌套其他Redis類型募疮,如散列、列表僻弹、集合等阿浓。
命令
向列表兩端增加元素,使用的指令如下:
LPUSH key value [value ...]
RPUSH key value [value ...]
LPUSH指令用來向列表左邊增加元素蹋绽,返回值表示增加元素后列表的長(zhǎng)度芭毙。當(dāng)有多個(gè)值元素時(shí),依次加入到列表卸耘。
LPUSH key v1 v2 v3
# 此時(shí)列表的元素為[v3, v2, v1]
RPUSH指令用來向列表右側(cè)增加元素退敦,和LPUSH類似,返回值為添加后的列表長(zhǎng)度蚣抗。
RPUSH key v4 v5
# 此時(shí)列表的元素為[v3, v2, v1, v4, v5]
從兩端獲取元素
LPOP key
RPOP key
BLPOP list1 list2... TIMEOUT
BRPOP list1 list2... TIMEOUT
LPOP指令從列表左側(cè)取出第一個(gè)元素侈百,取出意味著先移除,再返回。LPOP后钝域,則原始列表的長(zhǎng)度減少1
讽坏。
LPOP a
# "3"
# 此時(shí)列表的元素為[2, 1, 4, 5]
RPOP指令從列表右側(cè)取出第一個(gè)元素,和LPOP指令類似例证,移除右側(cè)第一個(gè)元素后路呜,并返回,列表長(zhǎng)度減少1
织咧。
RPOP a
# "5"
# 此時(shí)列表元素為[2, 1, 4]
BLPOP指令從指定的列表(list1拣宰,list2支持多個(gè)列表)左側(cè)彈出元素,當(dāng)列表沒有元素時(shí)烦感,會(huì)阻塞列表直到TIMEOUT超時(shí),TIMEOUT=0
時(shí)會(huì)一直阻塞下去膛堤。
當(dāng)列表為空時(shí)手趣,返回nil
(只有TIMEOUT非0時(shí),到期后沒有獲取到數(shù)據(jù)肥荔,就返回nil
)绿渣,否則返回成對(duì)的數(shù)據(jù),第一個(gè)元素為被彈出得列表key(list1)燕耿,第二個(gè)元素為彈出的數(shù)據(jù)中符。
# 客戶端1
BLPOP mylist 0
# 此時(shí)客戶端阻塞,當(dāng)客戶端2放入數(shù)據(jù)后誉帅,立即彈出數(shù)據(jù)
1) "mylist"
2) "1"
(19.50s)
# 最后的時(shí)間標(biāo)識(shí)阻塞開始知道彈出數(shù)據(jù)的時(shí)間
# 客戶端2
PUSH mylist 1 2
BRPOP指令同BLPOP指令基本功能一致淀散,只是彈出方向?yàn)榱斜碛覀?cè)。
獲取列表長(zhǎng)度
LLEN key
LLEN指令可以查詢一個(gè)列表的長(zhǎng)度蚜锨,當(dāng)key不存在時(shí)返回0
档插。Redis的設(shè)計(jì),有記錄列表長(zhǎng)度的信息亚再,因此讀取列表長(zhǎng)度郭膛,將會(huì)直接返回長(zhǎng)度值,因此其時(shí)間負(fù)責(zé)讀為O(1)氛悬,性能較高则剃。
LLEN ab #不存在
# (integer) 0
LLEN a
# (integer) 3
查詢列表子集
LRANGE key start stop
LRANGE通常會(huì)比LPOP、RPOP更為常用如捅,后者可能主要是作為棧棍现、隊(duì)列來使用,相對(duì)來說使用不是很頻繁(隊(duì)列采用MQ的可能性更大)伪朽;Redis的隊(duì)列作為熱門條目轴咱、個(gè)人收藏列表等更為常見,其讀取的操作跟多為子集列表;配合start和stop可以實(shí)現(xiàn)任意子集的讀取朴肺,Redis的列表索引從0
開始窖剑。
# 仍使用之前的a列表[2, 1, 4]
LRANGE a 0 1
# "2" "1"
LRANGE在讀取列表子集時(shí),返回后戈稿,不會(huì)刪除列表元素西土,在獲取子集時(shí),包含stop位置的元素鞍盗,如上述指令中需了,stop=1
,則會(huì)返回所謂位置1
的元素般甲。
start
和stop
支持負(fù)值肋乍,當(dāng)索引位置為負(fù)值時(shí),表示從右側(cè)開始返回敷存,-1
表示右側(cè)第一個(gè)元素墓造,-2
表示右側(cè)第二個(gè)元素,依次類推锚烦。
(當(dāng)stop超過了列表長(zhǎng)度觅闽,則實(shí)際的stop位置為右邊第一個(gè)元素)
(如果start > stop,則返回空列表)
# 返回從左側(cè)第一個(gè)元素開始涮俄,到右側(cè)第一個(gè)元素蛉拙,因此該指令返回列表的全部元素
LRANGE a 0 -1
# "2" "1" "4"
# stop=4超過了列表長(zhǎng)度, 則會(huì)返回全部數(shù)據(jù),到最右邊元素為止
LRANGE a 0 4
# "2" "1" "4"
LRANGE a -1 -4
# start > stop彻亲,返回空列表
LRANGE a 2 1
(empty list or set)
LRANGE a -1 -2
(empty list or set)
刪除列表指定元素
LREM key count value
LREM指令用于刪除key
列表中孕锄,指定的元素,會(huì)按照一定的方向(從左往右或從右往左)睹栖,刪除當(dāng)前方向上硫惕,前count
個(gè)值為value
的元素。返回值為刪除的元素個(gè)數(shù)野来。
count=0
恼除,刪除列表中所有的value
元素
count>0
,從左向右曼氛,刪除前count
個(gè)值為value
的元素
count<0
豁辉,從右向左,刪除前abs(count)
個(gè)值為value
的元素
LRANGE a 0 -1
# "1" "2" "1" "4" "1"
LREM a 2 1
# (integer) 2
LRANGE a 0 -1
# "2" "4" "1"
LREM a -2 1
# (integer) 1
LRANGE a 0 -1
# "2" "4"
LPUSH a 4
RPUSH a 4
LRANGE a 0 -1
# "4" "2" "4" "4"
LREM a 0 4
#(integer) 3
LRANGE a 0 -1
# "2"
獲取指定索引的值
LINDEX key index
LINDEX指令用于返回key
列表指定索引index
位置的值舀患。
index >= 0
徽级,從左邊開始查找,索引從0
開始
index < 0
聊浅,從右邊開始查找餐抢,最右側(cè)第一個(gè)元素索引為-1
當(dāng)
index
超出列表長(zhǎng)度现使,則返回空nil
LRANGE a 0 -1
# "1" "2" "3"
LINDEX a 1
# "2"
LINDEX a -2
# "2"
LINDEX a 3
# (nil)
設(shè)置指定索引的值
LSET key index value
LSET指令將key
列表的index
索引位置設(shè)置值為value
。
index >= 0
旷痕,從左邊開始碳锈,對(duì)指定索引位置設(shè)置為value
index < 0
,從右邊開始欺抗,對(duì)指定索引位置設(shè)置為value
index
超出列表范圍(無(wú)論是大于0還是小于0)售碳,均報(bào)錯(cuò):超出索引范圍
LRANGE a 0 -1
# "1" "2" "3"
LSET a 1 4
# OK
LRANGE a 0 -1
# "1" "4" "3"
LSET a -2 5
# OK
LRANGE a 0 -1
# "1" "5" "3"
LSET a 3 6
# (error) ERR index out of range
往列表中插入元素
LINSERT key BEFORE|AFTER pivot value
LINSERT指令,從左到右绞呈,找到值為pivot
的元素贸人,并將值value
插入到pivot
之前(BEFORE),或之后(AFTER)佃声;如果pivot
在列表中有多個(gè)艺智,則從左找到的第一個(gè)進(jìn)行插入。
當(dāng)
pivot
元素存在于列表中圾亏,插入完成力惯,返回插入后的列表長(zhǎng)度當(dāng)
pivot
不存在時(shí),返回-1
當(dāng)
key
不存在時(shí)召嘶,返回0
如果要操作的
key
存在,且不是列表哮缺,則異常
LRANGE a 0 -1
# "1" "5" "3"
LINSERT a AFTER 5 4
# (integer) 4
LRANGE a 0 -1
# "1" "5" "4" "3"
LINSERT a BEFORE 5 4
# (integer) 5
LRANGE a 0 -1
# "1" "4" "5" "4" "3"
LINSERT a BEFORE 4 6 # 有多個(gè)4弄跌,從左邊找到第一個(gè)4,進(jìn)行插入操作
# (integer) 6
LRANGE a 0 -1
# "1" "6" "4" "5" "4" "3"
LINSERT a BEFORE 0 23 # 未找到0尝苇,返回-1
# (integer) -1
LINSERT aa BEFORE 1 1 # aa不存在铛只,返回0
# (integer) 0
列表裁剪指令LTRIM
LTRIM key start stop
LTRIM指令對(duì)一個(gè)列表進(jìn)行刪除指定范圍(start
和stop
)之外的所有元素,最終保留為start
至stop
之間的元素糠溜,包括start
和stop
位置的元素淳玩。不在這個(gè)范圍的元素都將被刪除。
start
非竿、stop
取值從0開始到末尾蜕着,可以為負(fù)值,表示從右側(cè)開始红柱,-1
為最右側(cè)元素當(dāng)
start > stop
時(shí)承匣,將清空所有的元素
LRANGE a 0 -1
# "1" "6" "4" "5" "4" "3"
LTRIM a 1 4
# OK
LRANGE a 0 -1
# "6" "4" "5" "4"
LTRIM a -3 -2
# OK
LRANGE a 0 -1
# "4" "5"
LTRIM a 1 0
# OK
LRANGE a 0 -1
(empty list or set)
移動(dòng)列表最后一個(gè)元素到新列表RPOPLPUSH
RPOPLPUSH source destionation
RPOPLPUSH指令,將從一個(gè)列表末尾(最右側(cè))彈出一個(gè)元素锤悄,并加入到目標(biāo)列表的左側(cè)韧骗;并返回該元素的值。這個(gè)過程是原子的零聚。當(dāng)源列表為空時(shí)袍暴,執(zhí)行該指令些侍,將不發(fā)生彈出和壓入操作,返回空政模。
LRANGE a 0 -1
# "3" "2" "1"
RPOPLPUSH a b
# "1"
LRANGE a 0 -1
# "3" "2"
LRANGE b 0 -1
# "1"