Redis List列表類型詳解(二)

Redis

List

基本的數據類型,列表,可以實現 棧 隊列

所有的list都以L開頭

### PUSH ###
# LPUSH key element [element ...] 可同時push多個值
127.0.0.1:6379> LPUSH list one #插入列表的頭部 棧頂
(integer) 1
127.0.0.1:6379> LPUSH list two
(integer) 2
127.0.0.1:6379> LRANGE list 0 -1 # 查看列表的全部元素 LRANGE key start stop
1) "two"
2) "one"
127.0.0.1:6379> LRANGE list 0 1
1) "two"
2) "one"
127.0.0.1:6379> RPUSH list right #插到隊列的尾部 棧的底部
(integer) 3
127.0.0.1:6379> LRANGE list 0 -1
1) "two"
2) "one"
3) "right"

### POP ###
127.0.0.1:6379> lpop list #移除列首 棧頂
"two"
127.0.0.1:6379> rpop list #移除列尾 棧底
"right"

### lindex key index###
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> lindex list 0 #類似數組從左到右 0 -> max 第一個元素是0 
"three"
127.0.0.1:6379> lindex list 1
"two"


### Llen key start stop查看長度 ###
127.0.0.1:6379> lpush list one
(integer) 1
127.0.0.1:6379> lpush list two
(integer) 2
127.0.0.1:6379> lpush list three
(integer) 3
127.0.0.1:6379> llen list #返回列表的長度
(integer) 3

### Lrem key count element 移除key中count個數指定元素 ###
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "two"
3) "three"
4) "two"
127.0.0.1:6379> lrem list 1 two
(integer) 1
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "three"
3) "two"

### ltrim key start stop  截斷###
127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "hello1"
3) "hello2"
4) "hello3"
127.0.0.1:6379> ltrim mylist 1 2
OK
127.0.0.1:6379> lrange mylist 0 -1
1) "hello1"
2) "hello2"

### rpoplpush source destination 移除列表的最後一個元素放入新列表中###
127.0.0.1:6379> lpush list hello
(integer) 1
127.0.0.1:6379> lpush list hello1
(integer) 2
127.0.0.1:6379> lpush list hello2
(integer) 3
127.0.0.1:6379> lpush list hello3
(integer) 4
127.0.0.1:6379> rpoplpush list list2
"hello"
127.0.0.1:6379> lrange list 0 -1
1) "hello3"
2) "hello2"
3) "hello1"
127.0.0.1:6379> lrange list2 0 -1
1) "hello"

### lset key index element ###
# 將列表中指定下標的值更新爲另一個值
# 如果不存在列表就會報錯 如果存在就會更新當前下標值

### linsert key BEFORE|AFTER pivot element

# 將world插入在item之前
127.0.0.1:6379> linsert list before item world
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "world"
2) "item"
3) "hello2"
4) "hello1"

# 將world插入在item之後
127.0.0.1:6379> linsert list after item world
(integer) 5
127.0.0.1:6379> lrange list 0 -1
1) "world"
2) "item"
3) "world"
4) "hello2"
5) "hello1"

小結

  • 實際上是一個雙向鏈表,before node after left right都可以插入

  • 如果key不存在,創建新鏈表

  • 如果key存在,新增內容

  • 如果移除了所有值,空鏈表,也代表不存在

  • 在兩邊插入或者改動值,效率高,中間元素效率低

  • 如果用LRANGE來獲取數據,起始位置越大,速度越慢

list底層數據結構

127.0.0.1:6379> object encoding list
"quicklist"

Redis自己構件了鏈表的實現(c語言)

typedef  struct listNode{
       //前置節點
       struct listNode *prev;
       //後置節點
       struct listNode *next;
       //節點的值
       void *value;  
}listNode
    
typedef struct list{
     //表頭節點
     listNode *head;
     //表尾節點
     listNode *tail;
     //鏈表所包含的節點數量
     unsigned long len;
     //節點值複製函數
     void (*free) (void *ptr);
     //節點值釋放函數
     void (*free) (void *ptr);
     //節點值對比函數
     int (*match) (void *ptr,void *key);
}list;

Redis鏈表特性:

①、雙端:鏈表具有前置節點和後置節點的引用,獲取這兩個節點時間複雜度都爲O(1)。

②、無環:表頭節點的 prev 指針和表尾節點的 next 指針都指向 NULL,對鏈表的訪問都是以 NULL 結束。

③、帶鏈表長度計數器:通過 len 屬性獲取鏈表長度的時間複雜度爲 O(1)。

④、多態:鏈表節點使用 void* 指針來保存節點值,可以保存各種不同類型的值。

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