在前幾篇咱們介紹了Redis類型中的字符串類型和哈希類型,今天咱們瞭解一下Redis中的列表類型。在Redis中列表類型,能夠簡單的理解爲存儲多個有序字符串的一種新類型,這種類型除了字符串類型中已有的功能外,還提供了其它的功能。如能夠對列表的兩端插入和彈出元素(在列表中的字符串均可以稱之爲元素),除此以外還能夠獲取指定的元素列表,而且還能夠經過索引下標獲取指定元素等等。下面咱們經過下圖來看一下Redis中列表類型的插入和彈出操做:redis
下面咱們看一下Redis中列表類型的獲取與刪除操做:學習
下面咱們看一下Redis列表類型的特色:測試
lindex命令
而且在Redis中列表類型的索引是從0開始的。ui
下面咱們仍是和學習其它數據類型同樣,咱們仍是先學習一下Redis列表類型的命令。編碼
命令spa
1、添加操做3d
1.從右邊插入元素code
rpush key value [value ...]
咱們看rpush命令在插入時,是有返回值的,返回值的數量就是當前列表中全部元素的個數。blog
咱們也能夠用下面的命令從左到右獲取當前列表中的全部的元素,也就是如上圖所示中那樣。索引
lrange 0 -1
2.從左邊插入元素
lpush key value [value ...]
lpush命令的返回值及用法和rpush命令同樣,這裏就不在介紹了,但經過上面的事例證實了咱們前面說的,由於當前key中已經有了3個元素了,因此咱們在執行插入命令時,返回的就是6而不是3,由於rpush命令和lpush命令的返回值並非當前插入元素的個數,而返回的是當前key中所有元素的個數。
3.向某個元素前或者後插入元素
linsert key BEFORE|AFTER pivot value
linsert命令在執行的時候首先會從當前列表中查找到pivot元素,其次在將這個新元素插入到pivot元素的前面或者後面。而且咱們經過上圖所示知道linsert命令在執行成功後也是會有返回值的,返回的結果就是當前列表中元素的個數。
2、查找
1.獲取指定範圍內的元素列表
lrange key start stop
lrange命令會獲取列表中指定索引範圍的全部元素。經過索引獲取列表主要有兩個特色:
2.獲取列表中指定索引下標的元素
lindex key index
3.獲取列表長度
llen key
3、刪除
1.從列表左側彈出元素
lpop key
lpop命令執行成功後會返回當前被刪除的元素名稱。
2.從列表右側彈出元素
rpop key
rpop命令和lpop命令的使用方式同樣,這裏不在作過多介紹了。
3.刪除指定元素
lrem key count value
lrem命令會將列表中等於value的元素刪除掉,而且會根據count參數,來決定刪除value的元素個數。下面咱們看一下count參數的使用說明:
咱們看上圖中的命令中,雖然咱們將count參數指定的是5,將value參數指定的是2,但因爲當前列表中只有一個2,因此,當前lrem命令最多隻能刪除1個元素,而且lrem命令也是有返回值的,也就是當前成功刪除元素的個數。
4.按照索引範圍修剪列表
ltrim key start stop
ltrim命令會直接保留start索引到stop索引的之間的元素,幷包括當前元素,而以外的元素則都會刪除掉,因此該命令也叫修剪列表。
而且有一點要注意ltrim命令不會返回當前的列表中元素的個數,而是返回改命令是否成功的狀態。
4、修改
1.修改指定索引下標的元素
lset key index value
5、阻塞操做
blpop key [key ...] timeout brpop key [key ...] timeout
blpop和brpop命令是lpop和rpop命令的阻塞版本,它們除了彈出方向不一樣之外,使用方法基本相同。
下面咱們看一下該命令的詳細使用。
因爲我期間向列表中插入了元素,不然上述命令將一直阻塞下去。
2.列表不爲空:若是timeout=0,而且列表不爲空時,則blpop和brpop命令會當即返回結果,不會阻塞。
下面咱們看一下blpop和brpop命令的注意事項。
當列表爲空時,上述命令會阻塞,若是向上述中的任何一個鍵中插入元素,則上述命令會直接返回該鍵的元素。
我同時啓動了3個客戶端,由於當前列表爲空,因此上述命令執行後會阻塞。若是此時我向該列表中插入元素,則只有第一個客戶端會有返回結果,由於第一個客戶端是第一個執行上述命令的。
下面咱們看一下列表中命令的相關時間複雜度。
操做類型 | 命令 | 時間複雜度 |
---|---|---|
添加 | 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) |
內部編碼
列表中的內部編碼有兩種,它們分別是:
下面咱們經過相關命令來驗證上述所說。
1.當元素個數較少而且沒有大元素時,內部編碼爲ziplist。
咱們看當咱們在列表中插入少許元素,而且沒有大元素時,返回的內部編碼並非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列表類型的使用場景。