Redis基礎(chǔ)數(shù)據(jù)類型——列表類型

列表類型

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的元素般甲。

startstop支持負(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)行刪除指定范圍(startstop)之外的所有元素,最終保留為startstop之間的元素糠溜,包括startstop位置的元素淳玩。不在這個(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"
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末岗宣,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子览徒,更是在濱河造成了極大的恐慌狈定,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,681評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件习蓬,死亡現(xiàn)場(chǎng)離奇詭異纽什,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)躲叼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門芦缰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人枫慷,你說我怎么就攤上這事让蕾。” “怎么了或听?”我有些...
    開封第一講書人閱讀 169,421評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵探孝,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我誉裆,道長(zhǎng)顿颅,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,114評(píng)論 1 300
  • 正文 為了忘掉前任足丢,我火速辦了婚禮粱腻,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘斩跌。我一直安慰自己绍些,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,116評(píng)論 6 398
  • 文/花漫 我一把揭開白布耀鸦。 她就那樣靜靜地躺著柬批,像睡著了一般。 火紅的嫁衣襯著肌膚如雪袖订。 梳的紋絲不亂的頭發(fā)上萝快,一...
    開封第一講書人閱讀 52,713評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音著角,去河邊找鬼揪漩。 笑死,一個(gè)胖子當(dāng)著我的面吹牛吏口,可吹牛的內(nèi)容都是我干的奄容。 我是一名探鬼主播冰更,決...
    沈念sama閱讀 41,170評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼昂勒!你這毒婦竟也來了蜀细?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,116評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤戈盈,失蹤者是張志新(化名)和其女友劉穎奠衔,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體塘娶,經(jīng)...
    沈念sama閱讀 46,651評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡归斤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,714評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了刁岸。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片脏里。...
    茶點(diǎn)故事閱讀 40,865評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖虹曙,靈堂內(nèi)的尸體忽然破棺而出迫横,到底是詐尸還是另有隱情,我是刑警寧澤酝碳,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布矾踱,位于F島的核電站,受9級(jí)特大地震影響疏哗,放射性物質(zhì)發(fā)生泄漏介返。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,211評(píng)論 3 336
  • 文/蒙蒙 一沃斤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧刃宵,春花似錦衡瓶、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至坦袍,卻和暖如春十厢,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背捂齐。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工蛮放, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人奠宜。 一個(gè)月前我還...
    沈念sama閱讀 49,299評(píng)論 3 379
  • 正文 我出身青樓包颁,卻偏偏與公主長(zhǎng)得像瞻想,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子娩嚼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,870評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容