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* 指针来保存节点值,可以保存各种不同类型的值。

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