网站建设具体需求,多国语言网站模板,爱站关键词,商城的网站建设list类型
类型介绍
列表类型 list 相当于 数组或者顺序表 list内部的编码方式更接近于 双端队列 #xff0c;支持头插 头删 尾插 尾删。
需要注意的是#xff0c;Redis的下标支持负数下标。 比如数组大小为5#xff0c;那么要访问下标为 -2 的值可以理解为访问 5 - 2 3 …list类型
类型介绍
列表类型 list 相当于 数组或者顺序表 list内部的编码方式更接近于 双端队列 支持头插 头删 尾插 尾删。
需要注意的是Redis的下标支持负数下标。 比如数组大小为5那么要访问下标为 -2 的值可以理解为访问 5 - 2 3
Redis中的数据是有序的但是注意这里的有序不是指排序数组中的升序或者降序而是指数据的顺序很关键。比如把元素位置调换之后得到的新的list与原来的list是不等价的。
同样的一个词在不同的上下文中它的意义可能是不一样的。 比如同步这个词在 线程之间和IO之间的意义就不同。
另外list还提供了其他的一些功能如图 关于lindex和lrem两个命令 在hash类型中是不允许有重复数据的也就是不能有重复的field。但是list可以有重复的值。 lpush / lrange
lpush
将⼀个或者多个元素从左侧放⼊头插到 list 中。
LPUSH key element [element ...] 时间复杂度只插⼊⼀个元素为 O(1), 插⼊多个元素为 O(N), N 为插⼊元素个数. 返回值插⼊后 list 的⻓度。 注意这里的插入是头插的方式如果有多个值那么会依次将这些值头插到list中。 如果key不存在那么会先创建key再加入如果key存在并且不是list类型那么会报错。 lrange
获取从 start 到 end 区间的所有元素左闭右闭。
LRANGE key start stop 时间复杂度O(N) 返回值指定区间的元素。 谈到下标那么往往就会关注超出范围的问题。 可以看到Redis的做法是尽可能的获取到指定区间的元素如果给定区间不合法比如超出下标那么依然会尽可能的获取到对应的内容。
lrange这里的l不是指left 而是指 list。
扩展一些超出下标范围的情况
对于C 会认为这是一个未定义的行为 对于Java会抛异常 对于Redis尽可能的获取到对应的内容。 lpushx / rpush / rpushx lpushx 在 key 存在时将⼀个或者多个元素从左侧放⼊头插到 list 中。不存在直接返回 LPUSHX key element [element ...] 时间复杂度只插⼊⼀个元素为 O(1), 插⼊多个元素为 O(N), N 为插⼊元素个数. 返回值插⼊后 list 的⻓度。 rpush
将⼀个或者多个元素从右侧放⼊尾插到 list 中。
这样依次插入的元素就是顺序的 lpush就是倒序的
RPUSH key element [element ...] 时间复杂度只插⼊⼀个元素为 O(1), 插⼊多个元素为 O(N), N 为插⼊元素个数. 返回值插⼊后 list 的⻓度。 rpushx
在 key 存在时将⼀个或者多个元素从右侧放⼊尾插到 list 中。
RPUSHX key element [element ...] 时间复杂度只插⼊⼀个元素为 O(1), 插⼊多个元素为 O(N), N 为插⼊元素个数. 返回值插⼊后 list 的⻓度。 lpushx 和 rpushx 这里的x可以理解为exists。 lpop / rpop
lpop
从 list 左侧取出元素即头删。 LPOP key 时间复杂度O(1) 返回值取出的元素或者 nil。 rpop
从 list 右侧取出元素即尾删。
RPOP key 时间复杂度O(1) 返回值取出的元素或者 nil。 总结
Redis的list其实就是一个双端队列从两头插入/删除元素的效率都是 O1 搭配 lpush / lpop 可以当作一个队列使用
搭配 rpush/ rpop 可以当作一个栈使用 lindex / linsert / llen
lindex
获取从左数第 index 位置的元素。
LINDEX key index 时间复杂度O(N) 返回值取出的元素或者 nil。 linsert
在特定位置插⼊元素。 LINSERT key BEFORE | AFTER pivot element 时间复杂度O(N) 返回值插⼊后的 list ⻓度。如果插入失败返回-1 因为list的结构不是数组所以lindex和linsert都需要遍历找到位置所以时间复杂度为ON这里的N指的就是list的长度当list的长度不大时还好如果list太长了那么这两个命令的效率就低了。
llen
获取 list ⻓度。
LLEN key 时间复杂度O(1) 返回值list 的⻓度。 另外之前说过list中是允许有重复值的那么在insert的时候如果选择的基准值有重复的那么是如何插入的呢 可以看见当基准值有重复值时Redis会从左向右遍历找到以第一个符合基准值的位置为主。 lrem
批量删除等于 value的值。 当count 0时从左往右删除 count个元素。
当count 0时从右往左删除 count 个元素 。
当count 0时删除所有符合要求的元素。
rem 其实时 remove的缩写。 图中演示的就是从左往右删除 2 个 值 1的元素。 ltrim / lset
ltrim
删除 除了 [left,right]区间之外的所有元素
ltrim key start stop 时间复杂度 ON lset
根据下标来修改元素
lset key index element 时间复杂度ON 另外这里如果下标越界了是会直接报错的跟lindex那里会返回一个nil是不同的。 blpop / brpop 阻塞版本命令 blpop/brpop key timeout 时间复杂度 O1 返回值取出来的元素或者 nil超时了 blpop 和 brpop 是 lpop 和 rpop 的阻塞版本和对应⾮阻塞版本的作⽤基本⼀致除了 • 在列表中有元素的情况下阻塞和⾮阻塞表现是⼀致的。但如果列表中没有元素⾮阻塞版本会理 解返回 nil但阻塞版本会根据 timeout阻塞⼀段时间期间 Redis 可以执⾏其他命令但要求执 ⾏该命令的客⼾端会表现为阻塞状态如图 2-22 所⽰。 • 命令中如果设置了多个键那么会从左向右进⾏遍历键⼀旦有⼀个键对应的列表中可以弹出元 素命令⽴即返回。 • 如果多个客⼾端同时多⼀个键执⾏ pop则最先执⾏命令的客⼾端会得到弹出的元素。 还可以针对多个key进行操作的返回最先取出来的二元组。 命令总结 list内部编码 Redis老版本的方式 现在的redis是用一个quicklist的结构。 在redis的配置文件种这个就是配置list的ziplist的最大长度的这里的-2表示的是等级。
redis配置文件的默认路径
cd /etc/redis list的应用场景
作为数组
list作为数组可以储存多个元素。 在mysql下存储表结构 在Redis下存储 查询起来还是mysql的功能要丰富一些。 作为消息队列 分频道的消息队列 比如我们刷抖音一个抖音界面有很多元素组成比如视频弹幕点赞和评论等等那么这些数据没必要由一个通道来传输可以将这些元素分为多个通道传输。这样的好处是可以解耦合。 微博timeline 每个⽤⼾都有属于⾃⼰的 Timeline微博列表现需要分⻚展⽰⽂章列表。此时可以考虑使⽤ 列表因为列表不但是有序的同时⽀持按照索引范围获取元素。 1每篇微博使⽤哈希结构存储例如微博中 3 个属性title、timestamp、content
hmset mblog:1 title xx timestamp 1476536196 content xxxxx
...
hmset mblog:n title xx timestamp 1476536196 content xxxxx 2向⽤⼾ Timeline 添加微博user:uid:mblogs 作为微博的键
lpush user:1:mblogs mblog:1 mblog:3
...
lpush user:k:mblogs mblog:9
这里插入list中的是哈希表的索引。 3分⻚获取⽤⼾的 Timeline例如获取⽤⼾ 1 的前 10 篇微博
keylist lrange user:1:mblogs 0 9
for key in keylist {hgetall key
} 但是这里会存在一些问题 1. 1 n 问题。即如果每次分⻚获取的微博个数较多需要执⾏多次 hgetall 操作此时可以考虑使⽤pipeline流⽔线模式批量提交命令或者微博不采⽤哈希类型⽽是使⽤序列化的字符串类型使⽤ mget 获取。 2. 分裂获取⽂章时lrange 在列表两端表现较好获取列表中间的元素表现较差此时可以考虑将列表做拆分。