redis(6):數據結構-List列表類型

如果要將redis中文章進行分頁展示到前端,但是中間有可能有的文章已經刪除,若用hash存儲,則需要判斷改文章是否存在。現在繼續看redis的第三種數據結構list,可以完全規避上面問題;


一、介紹

在這裏插入圖片描述
Redis將列表數據結構命名爲list而不是array,是因爲列表的存儲結構用的是鏈表而不是數組,而且鏈表還是雙向鏈表。因爲它是鏈表,所以隨機定位性能較弱,首尾插入刪除性能較優。如果list的列表長度很長,使用時我們一定要關注鏈表相關操作的時間複雜度。

這種特性使列表類型能非常快速地完成關係數據庫難以應付的場景:如社交網站的新鮮事,我們關心的只是最新的內容,使用列表類型存儲,即使新鮮事的總數達到幾千萬個,獲 取其中最新的100條數據也是極快的。同樣因爲在兩端插入記錄的時間複雜度是O(1),列表類型也適合用來記錄日誌,可以保證加入新日誌的速度不會受到已有日誌數量的影響。 藉助列表類型,Redis還可以作爲隊列使用.

與散列類型鍵最多能容納的字段數量相同,一個列表類型鍵最多能容納2的32次方−1個元素。


二、命令

1.向列表兩端增加元素

LPUSH key value [value …]
RPUSH key value [value …] 

LPUSH命令用來向列表左邊增加元素,返回值表示增加元素後列表的長度。
redis> LPUSH numbers 1
(integer) 1
在這裏插入圖片描述


LPUSH命令還支持同時增加多個元素,例如:
redis> LPUSH numbers 2 3
(integer) 3

在這裏插入圖片描述

2.從兩端彈出元素

LPOP key  從列表左邊彈出第一個(1將列表左邊元素移除,2返回被移除的元素值)
RPOP key 從列表右側彈出第一個

3.獲取列表中元素個數

LLEN numbers 類似SQL中count

4.獲得列表片段

LRANGE key start stop 從key列表中獲取下標從start到stop的元素(包含兩端,下標從零開始)

5.刪除指定的值

LREM key count value

LREM命令會刪除列表中前count個值爲value的元素,返回值是實際刪除的元素個數。根 據count值的不同,LREM命令的執行方式會略有差異。

  1. 當 count > 0時 LREM 命令會從列表左邊開始刪除前 count 個值爲 value的元素。
  2. 當 count < 0時 LREM 命令會從列表右邊開始刪除前|count|個值爲 value 的元素。
  3. 當 count = 0是 LREM命令會刪除所有值爲 value的元素。

三、實踐

1.存儲文章ID列表

設計key=posts:list記錄文章ID列表,發佈新文章時候lpush即可加入,刪除文章lrem posts:list 1 即可;
注意:如果文章過多,要修改中間文章,性能較差(鏈表中找到中間元素性能慢)

2.存儲評論列表

讀取評論時需要獲得評論的全部數據(評論者姓名,聯繫方式,評 論時間和評論內容),不像文章一樣有時只需要文章標題而不需要文章正文。所以適合將一 條評論的各個元素序列化成字符串後作爲列表類型鍵中的元素來存儲。
我們使用列表類型鍵 post:文章ID:comments來存儲某個文章的所有評論。發佈評論的僞 代碼如下(以ID爲42的文章爲例):

//將評論序列化成字符串 
$serializedComment = serialize($author, $email, $time, $content) 
LPUSH post:42:comments, $serializedComment 

讀取評論時同樣使用LRANGE命令即可


四、命令拾遺

1.獲得/設置指定索引的元素值

LINDEX key index 
LSET key index value

如果要將列表類型當作數組來用,LINDEX命令是必不可少的。LINDEX命令用來返回 指定索引的元素,索引從0開始

2.只保留列表指定片段

LTRIM key start end 

LTRIM 命令可以刪除指定索引範圍之外的所有元素,其指定列表範圍的方法和LRANGE 命令相同。
LTRIM命令常和LPUSH命令一起使用來限制列表中元素的數量,比如記錄日誌時我們希 望只保留最近的100條日誌,則每次加入新元素時調用一次LTRIM命令即可;

3.向列表中插入元素

LINSERT key BEFORE|AFTER pivot value 

LINSERT 命令首先會在列表中從左到右查找值爲 pivot 的元素,然後根據第二個參數是 BEFORE還是AFTER來決定將value插入到該元素的前面還是後面。 LINSERT命令的返回值是插入後列表的元素個數;

4.將元素從一個列表轉到另一個列表

 RPOPLPUSH source destination 

RPOPLPUSH是個很有意思的命令,從名字就可以看出它的功能:先執行RPOP命令再 執行LPUSH命令
RPOPLPUSH命令會先從source列表類型鍵的右邊彈出一個元素,然後將 其加入到destination列表類型鍵的左邊,並返回這個元素的值,整個``過程是原子的。其具體實 現可以表示爲僞代碼:

def rpoplpush ($source, $destination) 
	$value = RPOP $source 
	LPUSH $destination, $value 
	return $value 

當把列表類型作爲隊列使用時,RPOPLPUSH 命令可以很直觀地在多個隊列中傳遞數據
當source和destination相同時,RPOPLPUSH命令會不斷地將隊尾的元素移到隊首,藉助 這個特性我們可以實現一個網站監控系統:使用一個隊列存儲需要監控的網址,然後監控程序不斷地使用 RPOPLPUSH 命令循環取出一個網址來測試可用性。這裏使用RPOPLPUSH命令的好處在於在程序執行過程中仍然可以不斷地向網址列表中加入新網址,而且整個系統容易擴展,允許多個客戶端同時處理隊列。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章