List(列表)
List简介
单键多值
他的底层实际是个双向链表,对双端的操作性能很高,通过索引下标的操作中间的节点性能会较差

127.0.0.1:6379> lpush list b1 b2 b3 #在列表的左边添加元素
(integer) 3
127.0.0.1:6379> lrange kist 0 -1
(empty list or set)
127.0.0.1:6379> lrange list 0 -1
1) "b3"
2) "b2"
3) "b1"
127.0.0.1:6379> rpush list a1 a2 a3 #在列表的右边添加元素
(integer) 6
127.0.0.1:6379> lrange list 0 -1 # 查看列表元素
1) "b3"
2) "b2"
3) "b1"
4) "a1"
5) "a2"
6) "a3"
127.0.0.1:6379> lpop list # 移除列表最左边的元素
"b3"
127.0.0.1:6379> type list
list
127.0.0.1:6379> rpop list # 移除列表最右边的元素
"a3"
127.0.0.1:6379> lrange list 0 -1
1) "b2"
2) "b1"
3) "a1"
4) "a2"
127.0.0.1:6379> lrange list 0 -1
1) "b2"
2) "b1"
3) "a1"
4) "a2"
127.0.0.1:6379> lindex list 1 # 通过列表下标获取元素
"b1"
127.0.0.1:6379> lindex list 0
"b2"
127.0.0.1:6379> lrange list 0 -1
1) "b2"
2) "b1"
3) "a1"
4) "a2"
127.0.0.1:6379> llen list # 返回列表的长度
(integer) 4
lrem # 移除指定数量的元素,
# 可用于取关
127.0.0.1:6379> lrange list 0 -1
1) "z3"
2) "z2"
3) "z1"
4) "z1"
5) "z1"
6) "b2"
7) "b1"
8) "a1"
9) "a2"
127.0.0.1:6379> lrem list 1 a1 # 移除指定 数量 元素 将列表 1个a1移除
(integer) 1
127.0.0.1:6379> lrange list 0 -1
1) "z3"
2) "z2"
3) "z1"
4) "z1"
5) "z1"
6) "b2"
7) "b1"
8) "a2"
127.0.0.1:6379> lrem list 3 z1 # 移除列表list 三个z1
(integer) 3
127.0.0.1:6379> lrange list 0 -1
1) "z3"
2) "z2"
3) "b2"
4) "b1"
5) "a2"
127.0.0.1:6379> lrem list 3 z3 # 想要移除3个z3,但列表只有1个,最终只移除了一个z3.如果需要移除的量,大于本身的量,就会将本身的量全部移除
(integer) 1
127.0.0.1:6379> lrange list 0 -1
1) "z2"
2) "b2"
3) "b1"
4) "a2"
127.0.0.1:6379> lrange list 0 -1
1) "z2"
2) "b2"
3) "b1"
4) "a2"
127.0.0.1:6379> ltrim list 1 2 # 截取列表指定片段,截取之后列表也会改变
OK
127.0.0.1:6379> lrange list 0 -1
1) "b2"
2) "b1"
127.0.0.1:6379> lrange list 0 -1
1) "b2"
2) "b1"
127.0.0.1:6379> rpoplpush list otherlist # 移除源列表(list)最后一个元素,并将移除的元素,添加到目标列表(otherlist)中
"b1"
127.0.0.1:6379> lrange list 0 -1
1) "b2"
127.0.0.1:6379> lrange otherlist 0 -1
1) "b1"
127.0.0.1:6379> lpush list b1 b2 b3 b4
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "b4"
2) "b3"
3) "b2"
4) "b1"
127.0.0.1:6379> EXISTS list # 判断列表是否存在
(integer) 1
127.0.0.1:6379> lset mylist 0 a1 # 如果列表不存在或者列表下标不存在,都会报错
(error) ERR no such key
127.0.0.1:6379> lset list 0 a1 # 如果列表存在或者列表下标存在,都会修改成功
OK
127.0.0.1:6379> lrange list 0 -1
1) "a1"
2) "b3"
3) "b2"
4) "b1"
# linsert:在指定元素前面或者后面插入元素
127.0.0.1:6379> lrange list 0 -1
1) "a1"
2) "b3"
3) "b2"
4) "b1"
127.0.0.1:6379> linsert list before a1 z1 # 在a1元素前面插入z1
(integer) 5
127.0.0.1:6379> lrange list 0 -1
1) "z1"
2) "a1"
3) "b3"
4) "b2"
5) "b1"
127.0.0.1:6379> linsert list after b1 z1 # 在b1元素后面插入z1
(integer) 6
127.0.0.1:6379> lrange list 0 -1
1) "z1"
2) "a1"
3) "b3"
4) "b2"
5) "b1"
6) "z1"
List底层原理
List的数据结构为快速链表QuickList
首先在列表元素较少的情况下会使用一块连续的内存存储,这个结构ZipList(压缩列表)
它将所有的元素紧挨着一起储存,分配的是一块连续的内存
当数据量比较多的时候才会改成 quicklist
因为普通的链表需要附加的指针空间太大,会比较浪费时间。比如列表的只是int类型的数据。结构上还需要两个额外的指针 prev 和 next

Redis将链表和ziplist结合起来组成了quicklist。也即是将ziplist使用双向指针串起来使用。

浙公网安备 33010602011771号