redis中的List底层是个双向链表(对操作两端性能高,对操作中间性能低),可以添加元素到List的左边或者右边
列表使用快速链表(quicklist)数据结构存储,而快速链表就是双向链表与压缩列表(数组 为了节省内存)的组合。
当数据量少时使用压缩列表,当数据量大时使用双向链表
Redis使用字节数组表示一个压缩列表,字节数组逻辑划分为多个字段,如图所示:
各字段含义如下:
- 1、zlbytes:压缩列表的字节长度,占4个字节,因此压缩列表最长(2^32)-1字节;
- 2、zltail:压缩列表尾元素相对于压缩列表起始地址的偏移量,占4个字节;
- 3、zllen:压缩列表的元素数目,占两个字节;那么当压缩列表的元素数目超过(2^16)-1怎么处理呢?此时通过zllen字段无法获得压缩列表的元素数目,必须遍历整个压缩列表才能获取到元素数目;
- 4、entryX:压缩列表存储的若干个元素,可以为字节数组或者整数;entry的编码结构后面详述;
- 5、zlend:压缩列表的结尾,占一个字节,恒为0xFF。
从左添加list key-value(v1被v2 v3 从左挤到右)
lpush k1 v1 v2 v3
从右添加list
rpush k1 v1 v2 v3
从左在下标处设置新值(在下标为0处设置新值)
lset k1 0 newv1
从左根据下标获取value
lindex v1 0
按照范围下标从左获取list( 下标0 -1就是获取完 0为第一个 -1为倒数第一个)
127.0.0.1:6379> lrange k1 0 -1
1) "v3"
2) "v2"
3) "v1"
从左在某个值前后添加新值(从左匹配的第一个值的前后 返回list的大小)
127.0.0.1:6379> linsert k1 after v2 v1
(integer) 4
127.0.0.1:6379> lrange k1 0 -1
1) "v3"
2) "v2"
3) "v1"
4) "abc"
127.0.0.1:6379> linsert k1 before v2 v1
(integer) 5
127.0.0.1:6379> lrange k1 0 -1
1) "v3"
2) "v1"
3) "v2"
4) "v1"
5) "abc"
从左删除指定数量的值(lrem 2为数量 v1为指定值 从左开始删除k1中2个v1)
127.0.0.1:6379> lrange k1 0 -1
1) "v3"
2) "v111"
3) "v1"
4) "v2"
5) "v1"
6) "abc"
127.0.0.1:6379> lrem k1 2 v1
(integer) 2
127.0.0.1:6379> lrange k1 0 -1
1) "v3"
2) "v111"
3) "v2"
4) "abc"
向左弹出值(1为弹出数量)(所有值被弹出,key就没有了)
lpop k1 1
127.0.0.1:6379> lrange k1 0 -1
1) "v2"
2) "v1"
向右弹出值(1为弹出数量)(所有值被弹出,key就没有了)
rpop k1 1
从key1的右边弹出一个值,插入key2的左边(返回弹出值)
rpoplpush k1 k2