Redis對象——列表(List)

前言

列表(list)類型是用來存儲多個(gè)有序的字符串,列表中的每個(gè)字符串稱為元素(element)瑟枫,一個(gè)列表最多可以存儲232-1個(gè)元素。在Redis中,可以對列表兩端插入(push)和彈出(pop)捅僵,還可以獲取指定范圍的元素列表、獲取指定索引下標(biāo)的元素等眨层。列表是一種比較靈活的數(shù)據(jù)結(jié)構(gòu)庙楚,它可以充當(dāng)棧和隊(duì)列的角色,在實(shí)際開發(fā)上有很多應(yīng)用場景趴樱。

列表類型有兩個(gè)特點(diǎn):

  • 列表中的元素是有序的馒闷,這就意味著可以通過索引下標(biāo)獲取某個(gè)元素或者某個(gè)范圍內(nèi)的元素列表。
  • 列表中的元素可以是重復(fù)的叁征。

一纳账、內(nèi)部實(shí)現(xiàn)

在Redis3.2版本以前列表類型的內(nèi)部編碼有兩種。

  • ziplist(壓縮列表):當(dāng)列表的元素個(gè)數(shù)小于list-max-ziplist-entries配置(默認(rèn)512個(gè))捺疼,同時(shí)列表中每個(gè)元素的值都小于list-max-ziplist-value配置時(shí)(默認(rèn)64字節(jié))疏虫,Redis會選用ziplist來作為列表的內(nèi)部實(shí)現(xiàn)來減少內(nèi)存的使用。
  • linkedlist(鏈表):當(dāng)列表類型無法滿足ziplist的條件時(shí)啤呼,Redis會使用linkedlist作為列表的內(nèi)部實(shí)現(xiàn)卧秘。
  • 而在Redis3.2版本開始對列表數(shù)據(jù)結(jié)構(gòu)進(jìn)行了改造,使用 quicklist 代替了 ziplist 和 linkedlist官扣。

二翅敌、常用命令

Redis列表對象常用命令如下表(點(diǎn)擊命令可查看命令詳細(xì)說明)。

命令 說明 時(shí)間復(fù)雜度
BLPOP key [key …] timeout 刪除醇锚,并獲得該列表中的第一元素哼御,或阻塞坯临,直到有一個(gè)可用 O(1)
BRPOP key [key …] timeout 刪除,并獲得該列表中的最后一個(gè)元素恋昼,或阻塞看靠,直到有一個(gè)可用 O(1)
BRPOPLPUSH source destination timeout 彈出一個(gè)列表的值,將它推到另一個(gè)列表液肌,并返回它;或阻塞挟炬,直到有一個(gè)可用 O(1)
LINDEX key index 獲取一個(gè)元素,通過其索引列表 O(N)
LINSERT key BEFORE AFTER pivot value在列表中的另一個(gè)元素之前或之后插入一個(gè)元素 O(N)
LLEN key 獲得隊(duì)列(List)的長度 O(1)
LPOP key 從隊(duì)列的左邊出隊(duì)一個(gè)元素 O(1)
LPUSH key value [value …] 從隊(duì)列的左邊入隊(duì)一個(gè)或多個(gè)元素 O(1)
LPUSHX key value 當(dāng)隊(duì)列存在時(shí)嗦哆,從隊(duì)到左邊入隊(duì)一個(gè)元素 O(1)
LRANGE key start stop 從列表中獲取指定返回的元素 O(S+N)
LREM key count value 從列表中刪除元素 O(N)
LSET key index value 設(shè)置隊(duì)列里面一個(gè)元素的值 O(N)
LTRIM key start stop 修剪到指定范圍內(nèi)的清單 O(N)
RPOP key 從隊(duì)列的右邊出隊(duì)一個(gè)元 O(1)
RPOPLPUSH source destination 刪除列表中的最后一個(gè)元素谤祖,將其追加到另一個(gè)列表 O(1)
RPUSH key value [value …] 從隊(duì)列的右邊入隊(duì)一個(gè)元素 O(1)
RPUSHX key value 從隊(duì)列的右邊入隊(duì)一個(gè)元素,僅隊(duì)列存在時(shí)有效 O(1)

三老速、使用場景

3.1 消息隊(duì)列

列表類型可以使用 rpush 實(shí)現(xiàn)先進(jìn)先出的功能粥喜,同時(shí)又可以使用 lpop 輕松的彈出(查詢并刪除)第一個(gè)元素,所以列表類型可以用來實(shí)現(xiàn)消息隊(duì)列

3.2 文章(商品等)列表

我們以博客站點(diǎn)為例橘券,當(dāng)用戶和文章都越來越多時(shí)额湘,為了加快程序的響應(yīng)速度,我們可以把用戶自己的文章存入到 List 中旁舰,因?yàn)?List 是有序的結(jié)構(gòu)锋华,所以這樣又可以完美的實(shí)現(xiàn)分頁功能,從而加速了程序的響應(yīng)速度箭窜。

  • 每篇文章我們使用哈希結(jié)構(gòu)存儲毯焕,例如每篇文章有3個(gè)屬性title、timestamp磺樱、content纳猫。
hmset acticle:1 title xx timestamp 1476536196 content xxxx
...
hmset acticle:k title yy timestamp 1476512536 content yyyy
...
  • 向用戶文章列表添加文章,user:{id}:articles作為用戶文章列表的鍵竹捉。
lpush user:1:acticles article:1 article3
...
lpush
...
  • 分頁獲取用戶文章列表续担,例如下面?zhèn)未a獲取用戶id=1的前10篇文章。
articles = lrange user:1:articles 0 9
for article in {articles}
{
    hgetall {article}
}

注意:使用列表類型保存和獲取文章列表會存在兩個(gè)問題活孩。

  • 如果每次分頁獲取的文章個(gè)數(shù)較多,需要執(zhí)行多次hgetall操作乖仇,此時(shí)可以考慮使用Pipeline批量獲取憾儒,或者考慮將文章數(shù)據(jù)序列化為字符串類型,使用mget批量獲取乃沙。
  • 分頁獲取文章列表時(shí)起趾,lrange命令在列表兩端性能較好,但是如果列表較大警儒,獲取列表中間范圍的元素性能會變差训裆,此時(shí)可以考慮將列表做二級拆分眶根,或者使用Redis3.2的quicklist內(nèi)部編碼實(shí)現(xiàn),它結(jié)合ziplist和linkedlist的特點(diǎn)边琉,獲取列表中間范圍的元素時(shí)也可以高效完成属百。

關(guān)于列表的使用場景可參考以下幾個(gè)命令組合:

  • lpush+lpop=Stack(棧)
  • lpush+rpop=Queue(隊(duì)列)
  • lpush+ltrim=Capped Collection(有限集合)
  • lpush+brpop=Message Queue(消息隊(duì)列)

參考:
https://www.laoyu.site/2020/%E6%8A%80%E6%9C%AF%E5%AE%9E%E8%B7%B5/redis/Redis%E5%AF%B9%E8%B1%A1%E2%80%94%E2%80%94%E5%88%97%E8%A1%A8(List)/

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市变姨,隨后出現(xiàn)的幾起案子族扰,更是在濱河造成了極大的恐慌,老刑警劉巖定欧,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件渔呵,死亡現(xiàn)場離奇詭異,居然都是意外死亡砍鸠,警方通過查閱死者的電腦和手機(jī)扩氢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來爷辱,“玉大人录豺,你說我怎么就攤上這事⊥邢” “怎么了巩检?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長示启。 經(jīng)常有香客問我兢哭,道長,這世上最難降的妖魔是什么夫嗓? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任迟螺,我火速辦了婚禮,結(jié)果婚禮上舍咖,老公的妹妹穿的比我還像新娘矩父。我一直安慰自己,他們只是感情好排霉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布窍株。 她就那樣靜靜地躺著,像睡著了一般攻柠。 火紅的嫁衣襯著肌膚如雪球订。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天瑰钮,我揣著相機(jī)與錄音冒滩,去河邊找鬼。 笑死浪谴,一個(gè)胖子當(dāng)著我的面吹牛开睡,可吹牛的內(nèi)容都是我干的因苹。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼篇恒,長吁一口氣:“原來是場噩夢啊……” “哼扶檐!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起婚度,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蘸秘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后蝗茁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體醋虏,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年哮翘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了颈嚼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,030評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡饭寺,死狀恐怖阻课,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情艰匙,我是刑警寧澤限煞,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站员凝,受9級特大地震影響衔憨,放射性物質(zhì)發(fā)生泄漏油狂。R本人自食惡果不足惜店枣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一辟狈、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧糖埋,春花似錦宣吱、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至祟敛,卻和暖如春倍奢,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背垒棋。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留痪宰,地道東北人叼架。 一個(gè)月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓畔裕,卻偏偏與公主長得像,于是被迫代替她去往敵國和親乖订。 傳聞我的和親對象是個(gè)殘疾皇子扮饶,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評論 2 355

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