Redis数据类型(list\set\zset)

"maybe it's why" 


List类型 

        列表类型是⽤来存储多个有序的字符串,列表中的每个字符串称为元素(element),⼀个列表最多可以存储个2^32 - 1个元素。在Redis中,可以对列表两端插⼊(push)和弹出(pop),还可以获取指定范围的元素列表、获取指定索引下标的元素等。列表是⼀种⽐较灵活的数据结构,它可以充当栈和队列的⻆⾊,在实际开发上有很多应⽤场景。

如何理解List有序?        

        有序的意思是要根据上下文来理解,比如,有序有时候是在谈它是升序或者是降序。而List的有序则是在谈其内部元素的"顺序",如果两个List中所含的元素、个数都是一样,但是元素内部里的顺序位置是不同的,那么这两个List不是同一个。

(1)  LPUSH\LPUSHX

        将⼀个或者多个元素从左侧放⼊(头插)到list中。

        在key存在时,将⼀个或者多个元素从左侧放⼊(头插)到list中。不存在,直接返回。 

(2) RPUSH\RPUSHX 

        将⼀个或者多个元素从右侧放⼊(尾插)到list中。

        在key存在时,将⼀个或者多个元素从右侧放⼊(尾插)到list中。尾插效果同头插差不多,这里也就不做什么演示了。

(3) LPOP\RPOP         

        从list左侧取出元素(即头删)。

        从list右侧取出元素(即尾删)。

(4) LINDEX

        获取从左数第index位置的元素。  

(5) LINSERT\LLEN

        在特定位置插⼊元素,可以携带选项<Before\After>选择插入在指定位置的后还是前。

        获取list⻓度。

(6) LREM \ LTRIM\ LSET

 

        保留指定区间,区间以外的全部删除。

        根据下标,更改元素。

(7) LRANGE 

        获取从start到end区间的所有元素,左闭右闭。

我们来谈谈越界访问?

         如果我们用LRANGE,写出如下的命令,会发生什么?

        显然,此时的end下标已经远远超过了list包含元素的个数,但是在redis的处理之中并没有报错,而是调整为获取适当范围的元素。 

(8) List与消息队列 

        因为List支持高效的头插头删、尾插尾删,所以List既可以当做一个栈,又可以当做一个队列使用。在Stream类型没有出来之前,Redis有一个典型的应用场景,就是把List作为消息队列。

BLPOP\BRPOP

        blpop和brpop是lpop和rpop的阻塞版本,和对应⾮阻塞版本的作⽤基本⼀致。

● 在列表中有元素的情况下,阻塞和⾮阻塞表现是⼀致的。但如果列表中没有元素,⾮阻塞版本会理解返回nil,但阻塞版本会根据timeout,阻塞⼀段时间,期间其余redis-cli可以执⾏其他命令,但要求执⾏该命令的客⼾端会表现为阻塞状态。

● 命令中如果设置了多个键,那么会从左向右进⾏遍历键,⼀旦有⼀个键对应的列表中可以弹出元
素,命令⽴即返回。

● 如果多个客⼾端同时多⼀个键执⾏pop,则最先执⾏命令的客⼾端会得到弹出的元素。

针对多个key进行操作:

         虽然List的这俩阻塞命令可以用来作为 “消息队列”,但它俩的功能实在有限,多少有点力不从心。  

List命令小结:

操作类型命令时间复杂度
添加rpush key value [value...]O(k),k为元素个数
lpush key value [value...]O(k),k为元素个数
linsert key <before/after> pivot valueO(k),k为pivot距离头尾的距离
查找lrange key start endO(s+n),s为start偏移量,n为start,end的范围
lindex key indexO(n),n是索引偏移量
llen keyO(1)
删除lpop\rpop keyO(1)
lrem key count valueO(k),k为元素个数
ltrim key start endO(k),k为元素个数
修改lset key index valueO(n),n是索引偏移量
阻塞操作blpop/brpopO(1)

 List的内部编码:

        列表类型的内部编码有两种:

• ziplist:作为列表的内部编码实现来减少内存消耗。
• linkedlist:当列表类型⽆法满⾜ziplist的条件时,Redis会使⽤linkedlist作为列表的内部实现。

        现如今,List底层的编码都是quicklist。

List使用场景

① 微博Timeline

        每个⽤⼾都有属于⾃⼰的Timeline(微博列表),现需要分⻚展⽰⽂章列表。此时可以考虑使⽤列表,因为列表不但是有序的,同时⽀持按照索引范围获取元素。
        

● 每篇微博使⽤哈希结构存储,例如微博中3个属性:title、timestamp、content:

hmset mblog:1 title xx timestamp 1476536196 content xxxxx
hmset mblog:2 title xx timestamp 1476536196 content xxxxx
......
hmset mblog:n title xx timestamp 1476536196 content xxxxx

● 向⽤⼾Timeline添加微博,user:<uid>:mblogs作为微博的键:

lpush user:1 :mblogs mblog:1 mblog:3
...
lpush user:n :mblogs mblog:1 mblog:3

● 分⻚获取⽤⼾的Timeline,例如获取⽤⼾1的前10篇微博:

keylist = lrange user:1:mblogs 0 9
for key in keylist {hgetall key
}


         


Set集合

        集合类型也是保存多个字符串类型的元素的,但和列表类型不同的是,元素之间是⽆序不允许重复。Redis除了⽀持集合内的增删查改操作,同时还⽀持多个集合取交集、并集、差集,合理地使⽤好集合类型,能在实际开发中解决很多问题。
 

(1) SADD\SMEMBERS\SISMEMBER

        将⼀个或者多个元素添加到set中。注意,重复的元素⽆法添加到set中。

        获取⼀个set中的所有元素,注意,元素间的顺序是⽆序的。

        判断⼀个元素在不在set中。

(2) SCARD 

        获取⼀个set的基数(cardinality),即set中的元素个数。

(3) SPOP\SREM        

         从set中删除并返回⼀个或者多个元素。注意,由于set内的元素是⽆序的,所以取出哪个元素实际是未定义⾏为,即可以看作随机的。        

        将指定的元素从set中删除。

(4) SMOVE

        将⼀个元素从源set取出并放⼊⽬标set中。
 

(5) SINTER\SUNION\SDIFF

        Redis中的Set集合也支持求交、求并、求差,这里也就不多说什么是交并差的概念了。

        获取给定set的交集中的元素。
        

        获取给定set的并集中的元素。
        获取给定set的差集中的元素。 

         

(6) SINTERSTORE\SUNIONSTORESDIFFSTORE

        我们上述的一系列操作,仅仅是将求得的结果输出在显示器上。但求这些结果更多的时候是需要被保存的。

        获取给定set的交集中的元素并保存到⽬标set中。

        获取给定set的并集中的元素并保存到⽬标set中。
 

        获取给定set的差集中的元素并保存到⽬标set中。

Set命令小结

命令时间复杂度
sadd key element [ element  ...]O(k),k为元素个数
srem key element [ element  ...]O(k),k为元素个数
scard keyO(1)
sismember key elementO(1)
srandmemeber key [count]O(n),n是count
spop key [count]O(n),n是count
smembers keyO(k),k为元素个数
sinter key [key...]\sinterstoreO(m*k),k为多个集合中元素最小的个数,m是键个数
sunion key [key...]\sunionstoreO(k),k为多个集合的元素总和
sdiff key [key...]\sdiffstoreO(k),k为多个集合的元素总和

Set内部编码

        集合类型的内部编码有两种:
• intset(整数集合):当集合中的元素都是整数并且元素的个数⼩于set-max-intset-entries配置
(默认512个)时,Redis会选⽤intset来作为集合的内部实现,从⽽减少内存的使⽤。
• hashtable(哈希表):当集合类型⽆法满⾜intset的条件时,Redis会使⽤hashtable作为集合
的内部实现。

Set使用场景:

① 标签

        集合类型⽐较典型的使⽤场景是标签(tag)。例如A⽤⼾对娱乐、体育板块⽐较感兴趣,B⽤⼾对历史、新闻⽐较感兴趣,这些兴趣点可以被抽象为标签。许多公司通过用户的这些隐私,对于增强⽤⼾体验和⽤⼾黏度都⾮常有帮助。

        一旦给某些用户打上标签后,通过Set集合的交并差计算,很容易找到两个人的共同爱好等相似的行为。基于这样的标签,衍生出"用户关系",例如谁谁和你有多少个共同好友之类的……

② SetUV

        如何衡量一个互联网产品?那就是看它的用户量。计算用户量的指标有两种方案:
PV: page view 用户每次访问这个服务器,都会产生一个pv,pv_count++。

UV: user view 每个用户访问服务器,产生一个uv,uv_count++,但如果是同一个用户多次请求访问这个服务器,uv则不会增加。

        所以,这个uv的过程自动带有去重的要求,Set集合类型正好可以满足需求。


Zset集合

        所谓的Zset集合本质是什么?其实伙同Set集合差别不大,而是新增了"权值"的概念。

        它保留了集合不能有重复成员的,其中有序集合中的每个元素都有⼀个唯⼀的浮点类型的分数(score)与之关联,使得有序集合中的元素是可以维护有序性的,但这个有序不是⽤下标作为排序依据⽽是⽤这个分数

        比如,我们想给列举一下三国战力standing:
        "一吕二赵三典韦,四关五马六张飞"。

        有序集合提供了获取指定分数和元素范围查找、计算成员排名等功能,合理地利⽤有序集合,可以帮助我们在实际开发中解决很多问题。

 

列表List vs 集合Set vs 有序集合Zset:

数据结构重复元素有序无序有序依据应用场景
列表List索引下标消息队列等
Set标签、社交等
Zset分数score排行榜系统等

Zset命令

ZADD:

        添加或者更新指定的元素以及关联的分数到zset中,分数应该符合double类型。 对于有序集合来说,Mermber里的更不像键值对,而是一组pair,因为它们互相都可以找到对方!      

• XX:仅仅⽤于更新已经存在的元素,不会添加新元素。
• NX:仅⽤于添加新元素,不会更新已经存在的元素。
• CH:默认情况下,ZADD返回的是本次添加的元素个数,但指定这个选项之后,就会还包含本次更
新的元素的个数。
• INCR:此时命令类似ZINCRBY的效果,将元素的分数加上指定的分数。此时只能指定⼀个元素和分数

 

 ZCARD\ZCOUNT:

        获取⼀个zset的基数(cardinality),即zset中的元素个数。

        返回分数在min和max之间的元素个数,默认情况下,min和max都是包含的。

        

ZRANGE\ZREVRANGE\ZRANGEBYSCORE:

        返回指定区间⾥的元素,分数按照升序。带上WITHSCORES可以把分数也返回。

        返回指定区间⾥的元素,分数按照降序。带上WITHSCORES可以把分数也返回。

        返回分数在min和max之间的元素,默认情况下,min和max都是包含的。 

ZPOPMAX\ZPOPMIN:

        删除并返回分数最⾼的count个元素。
        删除并返回分数最低的count个元素。

        其中还有BZPOPMIN\BZPOPMAX这两个命令,这是它们的阻塞版本,也就不再此做过多讲解。         

ZRANK\ZREVRANK:


        返回指定元素的排名,升序。
        返回指定元素的排名,降序。

ZREM:

        删除指定的元素。              


 

 ZINCRBY:

        为指定的元素的关联分数添加指定的分数值。

        为指定的元素的关联分数添加指定的分数,并且会移动元素保证其有序。

ZINTERSTORE\ZUNIONSTORE\ZDIFFSTORE:

        Zset有序集合也有支持交并差的运算。

        求出给定有序集合中元素的交集并保存进⽬标有序集合中,在合并过程中以元素为单位进⾏合并,元素对应的分数按照不同的聚合⽅式和权重得到新的分数。

        求出给定有序集合中元素的并集并保存进⽬标有序集合中,在合并过程中以元素为单位进⾏合并,元素对应的分数按照不同的聚合⽅式和权重得到新的分数。

        求出给定有序集合中元素的差集并保存进⽬标有序集合中,在求差集过程中以元素为单位进⾏合并,元素对应的分数按照不同的聚合⽅式和权重得到新的分数。 

        也许你会疑问,为什么我们很多命令也是支持多个keys,比如说zadd、mget、mset等等,为什么这些命令没有要求写明需要多少个key呢?

        其实你看这些命令的差别就在于,Zset有序集合系列如果不写明key有多少个,有可能会让key和参数搞混淆。

Zset命令小结:

命令时间复杂度
zadd key score member [score member]O(k*log(n)) ,k是添加成员个数,n是当前有序集合元素个数
zcard keyO(1)
zscore key memberO(1)
zrank/zrevrank key member O(log(n)),n是当前有序集合的个数
zrem key member [member...]

O(k*log(n)),k是删除成员的个数,n是当前有序集合的元素个数

zincrby key increment memberO(log(n)),n是当前有序集合的个数
zrange/zrevrange key start end [withsocres]O(k+log(n)),k是删除成员的个数,n是当前有序集合的元素个数
zcountO(log(n)),n是当前有序集合的个数
zremrangebyrank key min maxO(k+log(n)),k获取成员的个数,n是当前有序集合的元素个数 
zremrangebyscore key min maxO(k+log(n)),k获取成员的个数,n是当前有序集合的元素个数 
zinterstore destination numkeys key [key...]

O(n*k) + O(m * log(m)),n是输入的集合中最小的元素个数,

k是集合个数,m是目标集合元素个数

zunion destination numkeys key [key ...]

O(n*k) + O(m * log(m)),n是输入的集合中最小的元素个数,

k是集合个数,m是目标集合元素个数

Zset内部编码:

        有序集合类型的内部编码有两种:

• ziplist:Redis会⽤ziplist来作为有序集合的内部实现,ziplist可以有效减少内存的使⽤。
• skiplist:当ziplist条件不满⾜时,有序集合会使⽤skiplist作为内部实现,因为此时ziplist的操作效率会下降。

        skiplist 是一种复杂链表,它一个节点可能存有多个下个节点的地址。但并非本节要细说的。

ZSet的应用场景:

        Zset有序集合最关键的应用场景无非就是一些排行有关的榜单: 比如说微博热搜、游戏等级排行等等,最关键的要点是,这些数值是可能随时进行变动的,随之而来的排名也会相应进行变化。

        当然,对于游戏排行榜,比如说啥段位、分数、等级十分清晰明了,可是遇到复杂度场景,比如说微博热搜:

 


本篇到此结束,感谢你的阅读。

祝你好运,向阳而生~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/111821.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot笔记——(狂神说)——待续

路线 javase: OOPmysql:持久化 htmlcssjsjquery框架:视图&#xff0c;框架不熟练&#xff0c;css不好; javaweb:独立开发MVC三层架构的网站了∶原始 ssm :框架:简化了我们的开发流程&#xff0c;配置也开始较为复杂; war: tomcat运行 spring再简化: SpringBoot - jar:内嵌tomca…

hive lateral view 实践记录(Array和Map数据类型)

目录 一、Array 1.建表并插入数据 2.lateral view explode 二、Map 1、建表并插入数据 2、lateral view explode() 3、查询数据 一、Array 1.建表并插入数据 正确插入数据&#xff1a; create table tmp.test_lateral_view_movie_230829(movie string,category array&…

多维时序 | Matlab实现BiLSTM-Adaboost和BiLSTM多变量时间序列预测对比

多维时序 | Matlab实现BiLSTM-Adaboost和BiLSTM多变量时间序列预测对比 目录 多维时序 | Matlab实现BiLSTM-Adaboost和BiLSTM多变量时间序列预测对比预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 多维时序 | Matlab实现BiLSTM-Adaboost和BiLSTM多变量时间序列预…

springboot中使用ElasticSearch

引入依赖 修改我们的pom.xml&#xff0c;加入spring-boot-starter-data-elasticsearch <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>编写配…

基于Java+SpringBoot+Vue前后端分离秒杀系统设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

数学建模:层次分析法

&#x1f506; 文章首发于我的个人博客&#xff1a;欢迎大佬们来逛逛 层次分析法 步骤描述 将问题条理化&#xff0c;层次化&#xff0c;构建出一个有层次的结构模型。层次分为三类&#xff1a;目标层&#xff0c;准则&#xff08;指标&#xff09;层&#xff0c;方案层。比…

Fooocus:一个简单且功能强大的Stable Diffusion webUI

Stable Diffusion是一个强大的图像生成AI模型&#xff0c;但它通常需要大量调整和提示工程。Fooocus的目标是改变这种状况。 Fooocus的创始人Lvmin Zhang&#xff08;也是 ControlNet论文的作者&#xff09;将这个项目描述为对“Stable Diffusion”和“ Midjourney”设计的重新…

SAP_ABAP_BDC录屏案例

SAP ABAP顾问能力模型梳理_企业数字化建设者的博客-CSDN博客SAP Abap顾问能力模型https://blog.csdn.net/java_zhong1990/article/details/132469977 一、实施步骤 1.1 SHDB --> 新建记录-->输入录制的tcode :BP,-->执行录屏操作-->录制结果封装成函数 1.2 SHDB …

机器学习的测试和验证(Machine Learning 研习之五)

关于 Machine Learning 研习之三、四&#xff0c;可到秋码记录上浏览。 测试和验证 了解模型对新案例的推广效果的唯一方法是在新案例上进行实际尝试。 一种方法是将模型投入生产并监控其性能。 这很有效&#xff0c;但如果你的模型非常糟糕&#xff0c;你的用户会抱怨——这…

PMP®证书增持 CSPM-2证书,含金量高,快来办理

2023年6月起&#xff0c;持有PMP证书的朋友可以直接增持一个同等级证书CSPM-2&#xff0c;不用重新考试&#xff0c;不用重新学习&#xff0c;原PMP证书不影响正常使用&#xff0c;相当于多了一个国标项目管理证书。 第一步准备资料 1、填写能力评价表 2、提供2张2寸蓝底彩照&…

胡歌深夜发文:我对不起好多人

胡歌的微博又上了热搜。 8月29日01:18分&#xff0c;胡歌微博发文称&#xff1a;“我尽量保持冷静&#xff0c;我对不起好多人&#xff0c;我希望对得起这短暂的一生”&#xff0c;并配了一张自己胡子拉碴的图&#xff0c;右眼的伤疤清晰可见。 不少网友留言称“哥你又喝多了吗…

共享数据-vue3

vuex方案 安装vuex4.x 两个重要变动&#xff1a; 去掉了构造函数Vuex&#xff0c;而使用createStore创建仓库 为了配合composition api&#xff0c;新增useStore函数获得仓库对象&#xff1b;获取路由对象使用useRouter global state 由于vue3的响应式系统本身可以脱离…

Python学习 -- 异常捕获技巧

在编写Python代码时&#xff0c;异常处理是确保程序稳定性的关键。Python提供了灵活的异常捕获机制&#xff0c;包括try...except语句、try...except...else语句和try...except...finally语句。本文将详细介绍这些异常处理技巧&#xff0c;并为每种情况提供代码案例。 一、try…

支付宝小程序商城源码开源运营版+模块化DIY+多套模板 一键创建小程序

分享一款支付宝小程序商城源码&#xff0c;源码开源可二开&#xff0c;已测试完美运营版&#xff0c;帮你一键搭建支付宝商城小程序&#xff0c;含多套模板、自由DIY功能和完整的搭建部署教程。程序支持除支付宝小程序商城制作外&#xff0c;还支持一键同步微信、抖音、百度、今…

uni-app开发小程序,radio单选按钮,点击可以选中,再次点击可以取消

一、实现效果&#xff1a; 二、代码实现&#xff1a; 不适用官方的change方法&#xff0c;自己定义点击方法。 动态判断定义的值是否等于遍历的值进行回显&#xff0c;如果和上一次点击的值一样&#xff0c;就把定义的值改为null <template><view><radio-group&…

springboot第37集:kafka,mqtt,Netty,nginx,CentOS,Webpack

image.png binzookeeper-server-start.shconfigzookeeper.properties.png image.png image.png 消费 image.png image.png image.png image.png image.png image.png image.png image.png image.png Netty的优点有很多&#xff1a; API使用简单&#xff0c;学习成本低。功能强大…

IoT DC3 是一个基于 Spring Cloud 的开源的、分布式的物联网(IoT)平台本地部署步骤

dc3 windows 本地搭建步骤&#xff1a; ​​ 必要软件环境 进入原网页# 务必保证至少需要给 docker 分配&#xff1a;1 核 CPU 以及 4G 以上的运行内存&#xff01; JDK : 推荐使用 Oracle JDK 1.8 或者 OpenJDK8&#xff0c;理论来说其他版本也行&#xff1b; Maven : 推荐…

opencv 案例05-基于二值图像分析(简单缺陷检测)

缺陷检测&#xff0c;分为两个部分&#xff0c;一个部分是提取指定的轮廓&#xff0c;第二个部分通过对比实现划痕检测与缺角检测。本次主要搞定第一部分&#xff0c;学会观察图像与提取图像ROI对象轮廓外接矩形与轮廓。 下面是基于二值图像分析的大致流程 读取图像将图像转换…

Ctenos7安装mysql-8.1.0/tomcat-9.0.80/LNMT部署

目录 一、实验拓扑 二、部署mysql 三、部署Tomcat 四、配置NGINX 五、 配置NGINX的双机热备提高可用性 一、实验拓扑 二、部署mysql 官网下载地址https://dev.mysql.com/downloads/mysql/ 1、移除mariadb&#xff0c;安装所需应用 mysql-8.1.0 社区版 安装说明官网下载地址…

【算法系列篇】位运算

文章目录 前言什么是位运算算法1.判断字符是否唯一1.1 题目要求1.2 做题思路1.3 Java代码实现 2. 丢失的数字2.1 题目要求2.2 做题思路2.3 Java代码实现 3. 两数之和3.1 题目要求3.2 做题思路3.3 Java代码实现 4. 只出现一次的数字4.1 题目要求4.2 做题思路4.3 Java代码实现 5.…