Redis列表類型

在前幾篇咱們介紹了Redis類型中的字符串類型和哈希類型,今天咱們瞭解一下Redis中的列表類型。在Redis中列表類型,能夠簡單的理解爲存儲多個有序字符串的一種新類型,這種類型除了字符串類型中已有的功能外,還提供了其它的功能。如能夠對列表的兩端插入和彈出元素(在列表中的字符串均可以稱之爲元素),除此以外還能夠獲取指定的元素列表,而且還能夠經過索引下標獲取指定元素等等。下面咱們經過下圖來看一下Redis中列表類型的插入和彈出操做:redis

img

下面咱們看一下Redis中列表類型的獲取與刪除操做:學習

img

下面咱們看一下Redis列表類型的特色:測試

  • 列表中全部的元素都是有序的。因此在Redis中列表類型是能夠經過索引獲取的,也就是上圖中的
lindex命令

而且在Redis中列表類型的索引是從0開始的。ui

  • 列表中的元素是能夠重複的。也就是說在Redis列表類型中,是能夠保存重複的元素,也就是以下圖所示:

img

下面咱們仍是和學習其它數據類型同樣,咱們仍是先學習一下Redis列表類型的命令。編碼

命令spa

1、添加操做3d

1.從右邊插入元素code

rpush key value [value ...]

img

咱們看rpush命令在插入時,是有返回值的,返回值的數量就是當前列表中全部元素的個數。blog

咱們也能夠用下面的命令從左到右獲取當前列表中的全部的元素,也就是如上圖所示中那樣。索引

lrange 0 -1

2.從左邊插入元素

lpush key value [value ...]

img

lpush命令的返回值及用法和rpush命令同樣,這裏就不在介紹了,但經過上面的事例證實了咱們前面說的,由於當前key中已經有了3個元素了,因此咱們在執行插入命令時,返回的就是6而不是3,由於rpush命令和lpush命令的返回值並非當前插入元素的個數,而返回的是當前key中所有元素的個數。


3.向某個元素前或者後插入元素

linsert key BEFORE|AFTER pivot value

img

linsert命令在執行的時候首先會從當前列表中查找到pivot元素,其次在將這個新元素插入到pivot元素的前面或者後面。而且咱們經過上圖所示知道linsert命令在執行成功後也是會有返回值的,返回的結果就是當前列表中元素的個數。


2、查找

1.獲取指定範圍內的元素列表

lrange key start stop

img

lrange命令會獲取列表中指定索引範圍的全部元素。經過索引獲取列表主要有兩個特色:

  • 索引下標從左到右分別是0到N-1,從右到左是-1到-N。
  • lrange命令中的end參數在執行時會包括當前元素的。並非全部的語言都是這樣的。如咱們要獲取列表中前兩個元素則能夠以下圖所示:

img

2.獲取列表中指定索引下標的元素

lindex key index

img


3.獲取列表長度

llen key

img


3、刪除

1.從列表左側彈出元素

lpop key

img

lpop命令執行成功後會返回當前被刪除的元素名稱。


2.從列表右側彈出元素

rpop key

img

rpop命令和lpop命令的使用方式同樣,這裏不在作過多介紹了。


3.刪除指定元素

lrem key count value

lrem命令會將列表中等於value的元素刪除掉,而且會根據count參數,來決定刪除value的元素個數。下面咱們看一下count參數的使用說明:

  • count > 0:表示從左到右,最多刪除count個元素。也就是以下圖所示:

img
咱們看上圖中的命令中,雖然咱們將count參數指定的是5,將value參數指定的是2,但因爲當前列表中只有一個2,因此,當前lrem命令最多隻能刪除1個元素,而且lrem命令也是有返回值的,也就是當前成功刪除元素的個數。
img

  • count < 0:從右到左,最多刪除count個元素。

img

  • count = 0:刪除全部元素。

img


4.按照索引範圍修剪列表

ltrim key start stop

ltrim命令會直接保留start索引到stop索引的之間的元素,幷包括當前元素,而以外的元素則都會刪除掉,因此該命令也叫修剪列表。

img

而且有一點要注意ltrim命令不會返回當前的列表中元素的個數,而是返回改命令是否成功的狀態。


4、修改

1.修改指定索引下標的元素

lset key index value

img


5、阻塞操做

blpop key [key ...] timeout
brpop key [key ...] timeout

blpop和brpop命令是lpop和rpop命令的阻塞版本,它們除了彈出方向不一樣之外,使用方法基本相同。

  • key [key ...]:能夠指定多個列表的鍵。
  • timeout:阻塞時間(單位:秒)

下面咱們看一下該命令的詳細使用。

  1. 列表爲空:若是timeout=3,則表示客戶端等待3秒後才能返回結果,若是timeout=0,則表示客戶端會一直等待,也就是會阻塞。

img
因爲我期間向列表中插入了元素,不然上述命令將一直阻塞下去。
2.列表不爲空:若是timeout=0,而且列表不爲空時,則blpop和brpop命令會當即返回結果,不會阻塞。
img


下面咱們看一下blpop和brpop命令的注意事項。

  • 若是使用blpop和brpop命令指定多個鍵時,blpop和brpop命令會從左到右遍歷鍵,而且一旦有一個鍵能返回元素,則客戶端會當即返回。

img
當列表爲空時,上述命令會阻塞,若是向上述中的任何一個鍵中插入元素,則上述命令會直接返回該鍵的元素。

  • 若是多個客戶端都對同一個鍵執行blpop或者brpop命令,則最早執行該命令的客戶端會獲取到該鍵的元素。

img
我同時啓動了3個客戶端,由於當前列表爲空,因此上述命令執行後會阻塞。若是此時我向該列表中插入元素,則只有第一個客戶端會有返回結果,由於第一個客戶端是第一個執行上述命令的。
img
img


下面咱們看一下列表中命令的相關時間複雜度。

操做類型 命令 時間複雜度
添加 rpush key value [value ...] O(k),k是元素的個數
添加 lpush key value [value ...] O(k),k是元素的個數
添加 linsert key BEFORE/AFTER pivot value O(n),n是pivot距離列表頭或者尾的距離
添加 lrange key start stop O(s + n),s是start偏移量,n是start到stop的範圍
添加 lindex key index O(n),n是索引的偏移量
添加 llen key O(1)
添加 lpop key O(1)
添加 rpop key O(1)
添加 lrem key count value O(n),n是列表長度
添加 ltrim key start stop O(n),n是要裁剪的元素個數
添加 lset key index value O(n),n是索引的偏移量
添加 blpop/brpop key [key ...] timeout O(1)

內部編碼

列表中的內部編碼有兩種,它們分別是:

  • ziplist(壓縮列表):當列表中元素個數小於512(默認)個,而且列表中每一個元素的值都小於64(默認)個字節。Redis會選擇用ziplist來做爲列表的內部實現來減小內存的使用。固然上述默認值也能夠經過相關參數修改:list-max-ziplist-entried(元素個數)、list-max-ziplist-value(元素值)。
  • linkedlist(鏈表):當列表類型沒法知足ziplist條件時,Redis會選擇用linkedlist做爲列表的內部實現。

下面咱們經過相關命令來驗證上述所說。

1.當元素個數較少而且沒有大元素時,內部編碼爲ziplist。
img
咱們看當咱們在列表中插入少許元素,而且沒有大元素時,返回的內部編碼並非ziplist而是quicklist。這又是什麼編碼呢。簡單來講,quicklist編碼是Redis3.2版本以後(包括當前版本)提供了一種新的內部編碼。它和ziplist和linkedlist編碼相比它結合了這兩種編碼的優點,具體的區別之後的文章中在作詳細介紹。因爲我電腦安裝的Redis的版本是4.0.9,在3.2版本以後因此,上述代碼執行後的內部編碼爲quicklist。


2.當元素個數超過512個元素時,內部編碼將變爲linkedlist。如下代碼都是本人在Redis4.0.9中的測試,因此上述的驗證本人沒有驗證成功。

import redis

r = redis.Redis(host='127.0.0.1', port=6379)

print('Key爲【listkey】的字節編碼爲【%s】' % r.object('encoding', 'listkey').decode('utf-8'))

for i in range(1,512):
    r.rpush('listkey', i)

print('Key爲【listkey的字節編碼爲【%s】' % r.object('encoding', 'listkey').decode('utf-8'))
Key爲【listkey】的字節編碼爲【quicklist】
Key爲【listkey的字節編碼爲【quicklist】

3.當列表中某個元素超過64個字節時,內部編碼也會變成linkedlist。如下代碼也是本人在Redis4.0.9中的測試,因此上述的驗證本人也沒有驗證成功。

import redis

r = redis.Redis(host='127.0.0.1', port=6379)

print('Key爲【listkey】的字節編碼爲【%s】' % r.object('encoding', 'listkey').decode('utf-8'))

value = ''

for i in range(1,512):
    value += str(i)

r.rpush('listkey', i)

print('Key爲【listkey的字節編碼爲【%s】' % r.object('encoding', 'listkey').decode('utf-8'))
Key爲【listkey】的字節編碼爲【quicklist】
Key爲【listkey的字節編碼爲【quicklist】

上述內容就是Redis列表類型的相關知識,若有不正確的地方,歡迎指出,在下一篇中,我將分享Redis列表類型的使用場景。

原文地址:http://jilinwula.com/article/...

相關文章
相關標籤/搜索