您好,登錄后才能下訂單哦!
一、概述:
1、List:允許出現重復的元素,list可以作為棧(先進后出)或者隊列(先進先出)。
頭元素和尾元素:頭元素指的是列表左端/前端第一個元素;尾元素指的是列表右端/后端第一個元素。
舉個例子,列表list包含三個元素:x, y, z,其中x是頭元素,而z則是尾元素。
空列表:指不包含任何元素的列表,Redis將不存在的key也視為空列表。
2、鏈表結構的小技巧:
針對鏈表結構的Value,Redis在其官方文檔中給出了一些實用技巧,如RPOPLPUSH命令,下面給出具體的解釋。
Redis鏈表經常會被用于消息隊列的服務,以完成多程序之間的消息交換。假設一個應用程序正在執行LPUSH操作向鏈表中添加新的元素,我們通常將這樣的程序稱之為"生產者(Producer)",而另外一個應用程序正在執行RPOP操作從鏈表中取出元素,我們稱這樣的程序為"消費者(Consumer)"。如果此時,消費者程序在取出消息元素后立刻崩潰,由于該消息已經被取出且沒有被正常處理,那么我們就可以認為該消息已經丟失,由此可能會導致業務數據丟失,或業務狀態的不一致等現象的發生。然而通過使用RPOPLPUSH命令,消費者程序在從主消息隊列中取出消息之后再將其插入到備份隊列中,直到消費者程序完成正常的處理邏輯后再將該消息從備份隊列中刪除。同時我們還可以提供一個守護進程,當發現備份隊列中的消息過期時,可以重新將其再放回到主消息隊列中,以便其它的消費者程序繼續處理。
二、應用場景:
獲得最新的10個登錄用戶信息:
1、使用數據庫方式需執行如下sql語句:
select * from loginuser order by logintime desc limit 10;
但是數據多的時候,全部數據都要受到影響,對數據庫的負載比較高,
必要情況還要需要對關鍵字段logintime設置索引,索引也比較耗費系統資源。
2、如果通過redis的list鏈表實現以上功能,就非常簡單。可以在list鏈表中只保留最新的10個登錄用戶,每進來一個新數據就刪除一個舊數據,每次就可以從鏈表中直接獲得需要的資源,極大節省各方面的資源。
3、redis的list還能緩存一些不經常修改的系統配置信息。
如緩存地址信息(國家、省份、城市、街道)、緩存用戶信息等等。
三、常用操作:
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> LPUSH languages python (integer) 1 # 加入重復元素 redis> LPUSH languages python (integer) 2 redis> LRANGE languages 0 -1 # 列表允許重復元素 1) "python" 2) "python" # 加入多個元素 redis> LPUSH mylist a b c (integer) 3 redis> LRANGE mylist 0 -1 1) "c" 2) "b" 3) "a"
2、lpushx(left pushx)方法:
LPUSHX key value
將值value插入到列表key的表頭,當且僅當key存在并且是一個列表。
和LPUSH命令相反,當key不存在時,LPUSHX命令什么也不做。
例如: # 情況1:對空列表執行LPUSHX redis> LLEN greet # greet是一個空列表 (integer) 0 redis> LPUSHX greet "hello" # 嘗試LPUSHX,失敗,因為列表為空 (integer) 0 # 情況2:對非空列表執行LPUSHX redis> LPUSH greet "hello" # 先用LPUSH創建一個有一個元素的列表 (integer) 1 redis> LPUSHX greet "good morning" # 這次LPUSHX執行成功 (integer) 2 redis> LRANGE greet 0 -1 1) "good morning" 2) "hello"
3、rpush(right push)方法:
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> RPUSH languages c (integer) 1 # 添加重復元素 redis> RPUSH languages c (integer) 2 redis> LRANGE languages 0 -1 # 列表允許重復元素 1) "c" 2) "c" # 添加多個元素 redis> RPUSH mylist a b c (integer) 3 redis> LRANGE mylist 0 -1 1) "a" 2) "b" 3) "c"
4、rpushx(right pushx)方法:
RPUSHX key value
將值value插入到列表key的表尾,當且僅當key存在并且是一個列表。
和RPUSH命令相反,當key不存在時,RPUSHX命令什么也不做。
例如: # 情況1:key不存在 redis> LLEN greet (integer) 0 redis> RPUSHX greet "hello" # 對不存在的key進行RPUSHX,PUSH失敗。 (integer) 0 # 情況2:key存在且是一個非空列表 redis> RPUSH greet "hi" # 先用RPUSH插入一個元素 (integer) 1 redis> RPUSHX greet "hello" # greet現在是一個列表類型,RPUSHX操作成功。 (integer) 2 redis> LRANGE greet 0 -1 1) "hi" 2) "hello"
5、lpop(left pop)方法:
LPOP key
移除并返回列表key的頭元素。
redis> LLEN course (integer) 0 redis> RPUSH course algorithm001 (integer) 1 redis> RPUSH course c++101 (integer) 2 redis> LPOP course # 移除頭元素 "algorithm001"
6、rpop(right pop)方法:
RPOP key
移除并返回列表key的尾元素。
redis> RPUSH mylist "one" (integer) 1 redis> RPUSH mylist "two" (integer) 2 redis> RPUSH mylist "three" (integer) 3 redis> RPOP mylist # 返回被彈出的元素 "three" redis> LRANGE mylist 0 -1 # 列表剩下的元素 1) "one" 2) "two"
7、llen方法:
LLEN key
返回列表key的長度。
如果key不存在,則key被解釋為一個空列表,返回0.
如果key不是列表類型,返回一個錯誤。
# 情況1:空列表 redis> LLEN job (integer) 0 # 情況2:非空列表 redis> LPUSH job "cook food" (integer) 1 redis> LPUSH job "have lunch" (integer) 2 redis> LLEN job (integer) 2
8、lrange方法:
LRANGE key start end
返回列表key中指定區間內的元素,區間以偏移量start和end指定。
下標(index)參數start和end都以0為底,也就是說,以0表示列表的第一個元素,以1表示列表的第二個元素,以此類推。
你也可以使用負數下標,以-1表示列表的最后一個元素,-2表示列表的倒數第二個元素,以此類推。
超出范圍的下標
超出范圍的下標值不會引起錯誤。
如果start下標比列表的最大下標end(LLEN list減去1)還要大,或者start > stop,LRANGE返回一個空列表。
如果stop下標比end下標還要大,Redis將stop的值設置為end。
redis> RPUSH fp-language lisp # 插入一個值到列表fp-language (integer) 1 redis> LRANGE fp-language 0 0 1) "lisp" redis> RPUSH fp-language scheme (integer) 2 redis> LRANGE fp-language 0 1 1) "lisp" 2) "scheme"
9、linsert方法:
LINSERT key BEFORE|AFTER pivot value
將值value插入到列表key當中,位于值pivot之前或之后。
當pivot不存在于列表key時,不執行任何操作。
當key不存在時,key被視為空列表,不執行任何操作。
如果key不是列表類型,返回一個錯誤。
redis> RPUSH mylist "Hello" (integer) 1 redis> RPUSH mylist "World" (integer) 2 redis> LINSERT mylist BEFORE "World" "There" (integer) 3 redis> LRANGE mylist 0 -1 1) "Hello" 2) "There" 3) "World" redis> LINSERT mylist BEFORE "go" "let's" # 對一個非空列表插入,查找一個不存在的pivot (integer) -1 # 失敗 redis> EXISTS fake_list # 對一個空列表執行LINSERT命令 (integer) 0 redis> LINSERT fake_list BEFORE "nono" "gogogog" (integer) 0 # 失敗
10、lset方法:
LSET key index value
將列表key下標為index的元素的值替換為value。
更多信息請參考LINDEX操作。
當index參數超出范圍,或對一個空列表(key不存在)進行LSET時,返回一個錯誤。
# 情況1:對空列表(key不存在)進行LSET redis> EXISTS list (integer) 0 redis> LSET list 0 item (error) ERR no such key # 情況2:對非空列表進行LSET redis> LPUSH job "cook food" (integer) 1 redis> LRANGE job 0 0 1) "cook food" redis> LSET job 0 "play game" OK redis> LRANGE job 0 0 1) "play game" # 情況3:index超出范圍 redis> LLEN list # 列表長度為1 (integer) 1 redis> LSET list 3 'out of range' (error) ERR index out of range
11、lrem方法:
LREM key count value
根據參數count的值,移除列表中與參數value相等的元素。
count的值可以是以下幾種:
count > 0: 從表頭開始向表尾搜索,移除與value相等的元素,數量為count。
count < 0: 從表尾開始向表頭搜索,移除與value相等的元素,數量為count的絕對值。
count = 0: 移除表中所有與value相等的值。
# 先創建一個表,內容排列是 # morning hello morning helllo morning redis> LPUSH greet "morning" (integer) 1 redis> LPUSH greet "hello" (integer) 2 redis> LPUSH greet "morning" (integer) 3 redis> LPUSH greet "hello" (integer) 4 redis> LPUSH greet "morning" (integer) 5 redis> LRANGE greet 0 4 # 查看所有元素 1) "morning" 2) "hello" 3) "morning" 4) "hello" 5) "morning" redis> LREM greet 2 morning # 移除從表頭到表尾,最先發現的兩個morning (integer) 2 # 兩個元素被移除 redis> LLEN greet # 還剩3個元素 (integer) 3 redis> LRANGE greet 0 2 1) "hello" 2) "hello" 3) "morning" redis> LREM greet -1 morning # 移除從表尾到表頭,第一個morning (integer) 1 redis> LLEN greet (integer) 2 redis> LRANGE greet 0 1 1) "hello" 2) "hello" redis> LREM greet 0 hello # 移除表中所有hello (integer) 2 # 兩個hello被移除 redis> LLEN greet (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> LRANGE alpha 0 -1 # 建立一個5元素的列表 1) "h" 2) "e" 3) "l" 4) "l" 5) "o" redis> LTRIM alpha 1 -1 # 刪除索引為0的元素 OK redis> LRANGE alpha 0 -1 # "h"被刪除 1) "e" 2) "l" 3) "l" 4) "o" # 情況2:stop下標比元素的最大下標要大 redis> LTRIM alpha 1 10086 OK redis> LRANGE alpha 0 -1 1) "l" 2) "l" 3) "o" # 情況3:start和stop下標都比最大下標要大,且start < sotp redis> LTRIM alpha 10086 200000 OK redis> LRANGE alpha 0 -1 # 整個列表被清空,等同于DEL alpha (empty list or set) # 情況4:start > stop redis> LRANGE alpha 0 -1 # 在新建一個列表 1) "h" 2) "u" 3) "a" 4) "n" 5) "g" 6) "z" redis> LTRIM alpha 10086 4 OK redis> LRANGE alpha 0 -1 # 列表同樣被清空 (empty list or set)
13、rpoplpush方法:
RPOPLPUSH source destination
命令RPOPLPUSH在一個原子時間內,執行以下兩個動作:
將列表source中的最后一個元素(尾元素)彈出,并返回給客戶端。
將source彈出的元素插入到列表destination,作為destination列表的的頭元素。
舉個例子,你有兩個列表source和destination,source列表有元素a, b, c,destination列表有元素x, y, z,執行RPOPLPUSH source destination之后,source列表包含元素a, b,destination列表包含元素c, x, y, z ,并且元素c被返回。
如果source不存在,值nil被返回,并且不執行其他動作。
如果source和destination相同,則列表中的表尾元素被移動到表頭,并返回該元素,可以把這種特殊情況視作列表的旋轉(rotation)操作。
# 相關數據 redis> RPUSH alpha a (integer) 1 redis> RPUSH alpha b (integer) 2 redis> RPUSH alpha c (integer) 3 redis> RPUSH alpha d (integer) 4 # 情況1:source和destination不同 redis> LRANGE alpha 0 -1 # 查看所有元素 1) "a" 2) "b" 3) "c" 4) "d" redis> RPOPLPUSH alpha reciver # 執行一次RPOPLPUSH看看 "d" redis> LRANGE alpha 0 -1 1) "a" 2) "b" 3) "c" redis> LRANGE reciver 0 -1 1) "d" redis> RPOPLPUSH alpha reciver # 再執行一次,確保rpop和lpush的位置正確 "c" redis> LRANGE alpha 0 -1 1) "a" 2) "b" redis> LRANGE reciver 0 -1 1) "c" 2) "d" # 情況2:source和destination相同 redis> RPOPLPUSH alpha alpha "c" redis> LRANGE alpha 0 -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> LPUSH mylist "World" (integer) 1 redis> LPUSH mylist "Hello" (integer) 2 redis> LINDEX mylist 0 "Hello" redis> LINDEX mylist -1 "World" redis> LINDEX mylist 3 # index不在mylist的區間范圍內 (nil)
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。