redis的学习(二)

4 哈希表

        哈希类型中的映射关系通常称为field-value,⽤于区分Redis整体的键值对(key-value), 注意这⾥的value是指field对应的值,不是键(key)对应的值,

 4.1 操作命令

hset:设置hash中指定的字段(field)的值(value)。

 HSET key field value [field value ...]

//一个命令可以设置多个filed,value

返回值:添加成功的f-v的个数。

hget:获取hash中指定字段的值。

 HGET key field

时间复杂度:O(1)

返回值:字段对应的值或者nil。

hexists:判断hash中是否有指定的字段。

HEXISTS key field

返回值:1表⽰存在,0表⽰不存在。

HDEL :删除hash中指定的字段。

HDEL key field [field ...],hdel删除的是key中的filed

时间复杂度:删除⼀个元素为O(1).删除N个元素为O(N).

返回值:本次操作删除的字段个数。没有的话返回0.

del操作就会直接将key整个删除。

hkeys:获取hash中的所有字段。该操作西安根据key找到对应的hash,然后再遍历hash

HKEYS key

时间复杂度:O(N),N为field的个数.

返回值:字段列表。

HVALS :获取hash中的所有的值。

 HVALS key 

时间复杂度:O(N),N为field的个数.

返回值:所有的值。 

HGETALL :获取hash中的所有字段以及对应的值。

 HGETALL key

 时间复杂度:O(N),N为field的个数.

返回值:字段和对应的值。

界面显示是一个k一个value,一一对应。

 

HMGET ⼀次获取hash中多个字段的值。

HMGET key field [field ...]

时间复杂度:只查询⼀个元素为O(1),查询多个元素为O(N),N为查询元素个数.

返回值:字段对应的值或者nil。

上述的hkeys,hvals,hgetal都是存在一定的风险的,hash的元素个数太多,执行命令就会耗很长的时间,从而阻塞redis。hscan也可以遍历redis的hash,但是它属于“渐进式遍历”l,即执行一次命令,就遍历一部分。

concorrenthashmap:是java标准库提供的线程安全的哈希表,在哈希表扩容的时候就是按照化整为零的方式进行的。

HLEN 获取hash中的所有元素的个数。

 HLEN key

时间复杂度:O(1)

返回值:字段个数。

HSETNX 在字段不存在的情况下,设置hash中的字段和值。

HSETNX key field value

时间复杂度:O(1)

返回值:1表⽰设置成功,0表⽰失败。

HINCRBY 将hash中字段对应的数值添加指定的值。

HINCRBY key field increment 

时间复杂度:O(1)

返回值:该字段变化之后的值

4.2 redis-hash的内部编码

        哈希的内部编码有两种:

        • ziplist(压缩列表):当哈希类型元素个数⼩于hash-max-ziplist-entries配置(默认512个)、 同时所有值都⼩于hash-max-ziplist-value配置(默认64字节)时,Redis会使⽤ziplist作为哈 希的内部实现,ziplist使⽤更加紧凑的结构实现多个元素的连续存储,所以在节省内存⽅⾯⽐ hashtable更加优秀。

        所谓压缩,rar,zip,gzip,7z实际上是一些具体的压缩算法,压缩的本质是针对数据进行重新编码,不同的数据有不同的特点,结合这些特点进行设计,重新编码之后能够缩小体积。

        ziplist内部的数据结构也是精心设计的,一个普通的hash表由于有些位置上有元素有些位置上没有元素会浪费一定的空间,ziplist目的是节省内存空间,但是读写元素的速度比较慢。

        1、如果hash中的元素比较少使用ziplist表示,如果元素的个数比较多就使用hashtable来表示;

        2、如果每一个value的值的长度比较短就使用ziplist表示,如果长度比价长就会转换为hashtable来表示。

         • hashtable(哈希表):当哈希类型⽆法满⾜ziplist的条件时,Redis会使⽤hashtable作为哈希 的内部实现,因为此时ziplist的读写效率会下降,⽽hashtable的读写时间复杂度为O(1)。

4.3 hash的应用

         作为缓存,存储结构话的数据,使用hash更好。

        上述结构性数据如果使用string类型的字符串,就需要使用json格式,如果使用string(json)来表示userinfo,如果只是想从内存中获取某个field,就需要吧整个json都读出来,解析成一个对象操作field,完成之后在转换成json字符串写回到内存中。

        如果使用hash的方式来表示userinfo,就可以使用field表示对象的每一个属性(数据库的每一个列),此时就可以方便的修改或获取每一个属性的值。

        故此使用hash的方式,读写field更加高效,但是付出的是空间的代价,需要控制哈希ziplist和hashtable两种内在的编码的转换,需要造成内存的极大消耗。

高内聚:将大部分有关联得东西放到一起。

耦合:多个模块/代码之间的关联关系,一般追求的是低耦合。 

        需要注意的是哈希类型和关系型数据库有两点不同之处:

         • 哈希类型是稀疏的,⽽关系型数据库是完全结构化的,例如哈希类型每个键可以有不同的field,⽽ 关系型数据库⼀旦添加新的列,所有⾏都要为其设置值,即使为null。

        • 关系数据库可以做复杂的关系查询,⽽Redis去模拟关系型复杂查询,例如联表查询、聚合查询等 基本不可能,维护成本⾼。

5.列表list

         list相当于数组或者顺序表。

        list内部的编码方式并非是一个简单的数组,而是类似于“双端队列”(deque)。

列表类型的特点:

         第⼀、列表中的元素是有序的(根据上下文区分),(有时候的有序是指升序和降序,这里的有序是指顺序),如果吧元素的位置进行颠倒,此时得到的list和之前的list的不等价的。

         第⼆、区分获取和删除的区别。lindex能获取元素的值,lrem也能返回被删除元素的值。

        第三、列表中的元素是允许重复的。像hash类型,其field是不能重复的。因为当前的list头和尾都能高效的插入删除元素,就可以把这个list当做是一个栈/队列来使用。

 5.1 操作命令

LPUSH :将⼀个或者多个元素从左侧放⼊(头插)到list中,可以一次插入一个或者多个。如果key已经存在,且key对应的value类型不是list,此时lpush命令就要报错

 LPUSH key element [element ...]  

时间复杂度:只插⼊⼀个元素为O(1),插⼊多个元素为O(N),N为插⼊元素个数.

返回值:插⼊后list的⻓度。

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

LRANGE key start stop

时间复杂度:O(N)

返回值:指定区间的元素。

 redis对于给定的不合法的区间获取元素的操作,会尽可能的在不合法的区间里面尽量多的获取元素。

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

LPUSHX key element [element ...]

时间复杂度:只插⼊⼀个元素为O(1),插⼊多个元素为O(N),N为插⼊元素个数.

返回值:插⼊后list的⻓度。 

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

RPUSHX key element [element ...]

时间复杂度:只插⼊⼀个元素为O(1),插⼊多个元素为O(N),N为插⼊元素个数.

返回值:插⼊后list的⻓度。 

RPUSHX :在key存在时,将⼀个或者多个元素从右侧放⼊(尾插)到list中。

 RPUSHX key element [element ...]

时间复杂度:只插⼊⼀个元素为O(1),插⼊多个元素为O(N),N为插⼊元素个数.

返回值:插⼊后list的⻓度。

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

LPOP key

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

RPOP key 

类似于队列:使用rpush和lpop;

类似于栈,使用rpush和rpop。

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

LINDEX key index 

lrem:从左边删除

lrem key count element

count要删除的个数,element要删除的值;

count>0:从左往右开始,删除遇到的count个element元素。

 count<0:从右往左开始,删除遇到的count个element元素。

count=0,删除所有的element元素。

ltrim:指定范围,范围内的保留,其余的删除

ltrim key start stop左闭右闭

 lset:根据下标修改元素

lset key index e

o(n)

5.2 阻塞版本命令

        阻塞:当前的线程不走了,代码不继续执行了,会在满足一定的条件后被唤醒。blpop和brpop。

        redis的list相当于阻塞队列,线程安全室通过单线程模型支持的。只支持队列为空的状态,不支持队列满的状态。即:

        但是阻塞版本会根据timeout,阻塞一段时间,器件redis可以执行其他命令。使用brpop和blpop的时候,是可以显式设置阻塞时间的。

        1、blpop和brpop都是可以同时去尝试获取多个key的列表的元素的。 

        2、如果多个客户端同时对一个key执行pop,则最先执行命令的客户端会得到弹出的元素。

blpop key [key..] timeout

这里的key可以是指定一个或者多个,每一个key对应一个list。

如果这些list有任何一个非空,blpop都能够把这里的元素给获取到,立即返回。

如果这些list都为空,此时就需要阻塞等待,等待其他的客户端往这些list中插入元素了,同时还可以设置超时时间。

返回结果首先是该key,其次是获取到的元素。

 5.3 命令小结

内部编码:

redis5之前:

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

         ziplist(压缩列表):当列表的元素个数⼩于list-max-ziplist-entries配置(默认512个),同时 列表中每个元素的⻓度都⼩于list-max-ziplist-value配置(默认64字节)时,Redis会选⽤ ziplist来作为列表的内部编码实现来减少内存消耗。

        linkedlist(链表):当列表类型⽆法满⾜ziplist的条件时,Redis会使⽤linkedlist作为列表的内部实现

当前以redis5v为例:

        ziplist(压缩列表):把数据按照更紧凑的压缩形式进行表示的,方便节省空间,但是当元素个数多了,操作起来效率会降低。

        linkedlist(链表):很好的应对元素个数较多的情况。

        quicklist:相当于链表和压缩列表的结合,整体是一个链表,但是链表的每一个节点都是一个压缩列表。每一个压缩列表都不让其过大,将多个压缩列表通过链式结构连接起来。

        对于ziplist最大空间的配置于:list-max-ziplist-size -2;表示最大的空间大小为8kb。

5.4 应用场景

1、用list作为数组这样的结构,来存储多个元素。

2、作为消息队列。

ps:谢谢观看,壁纸来源于【PV】下次旅行(又名大理风景片)-刘力菲_哔哩哔哩_bilibili

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

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

相关文章

前端编码技巧与规范

当我们完成项目的构建&#xff0c;进入开发阶段的时候&#xff0c;除了你需要了解框架本身的知识点外&#xff0c;我们还需要提前掌握一些项目的编码技巧与规范&#xff0c;在根源上解决之后因编码缺陷而导致的项目维护困难、性能下降等常见问题&#xff0c;为项目多人开发提供…

谷歌广告关键词出价根据什么来判断?

投放广告的目的是为了盈利&#xff0c;而关键字的出价直接关系到广告费用的支出。因此&#xff0c;设定出价上限时&#xff0c;不仅要参考关键字规划师的建议&#xff0c;还需结合广告的盈利表现来合理判断。 可以在谷歌广告账户的后台查看“平均每次点击费用”和“每次点击的…

《我在技术交流群算命》(二):QGraphicsItem怎么写自定义信号啊(QObject多继承顺序问题)

某位群友突然无征兆的抛出以下问题&#xff1a; QGraphicsItem怎么写自定义信号啊 看到这个问题的时候我是比较疑惑的&#xff0c;按鄙人对 Qt 的了解&#xff0c;自定义信号只需: 继承QObject类中加入Q_OBJECT宏声明一个信号并使用 但该群友毕竟也不是一个Qt新手&#xff0…

filebeat采集应用程序日志和多行匹配

1 filebeat采集nginx json日志 01 修改nginx的日志为json格式 elk93节点安装nginx&#xff0c;注释掉默认的nginx日志格式&#xff1a;# access_log /var/log/nginx/access.log;&#xff0c;在下方增加以下配置。然后重启nginx log_format wzy_nginx_json {"timestamp&…

大语言模型提示技巧(二)-给模型时间思考

在与大语言模型交互的时候&#xff0c;如果模型给出了错误的结论&#xff0c;不要着急否定大模型的能力&#xff0c;我们应当尝试重新构建查询&#xff0c;请求模型在提供它的最终答案之前进行一系列相关的推理。也就是说&#xff0c;如果给模型一个在短时间或用少量文字无法完…

深入剖析MySQL数据库架构:核心组件、存储引擎与优化策略(一)

sql语句分为两大类&#xff1a;查询&#xff08;select&#xff09;、增删改----修改&#xff08;update&#xff09; select语句的执行流程 执行sql语句的流程&#xff1a;连接数据库、缓存查询、解析器、优化器、执行器、存储引擎操作数据 客户端&#xff1a;图形界面工具…

【AimRT】现代机器人通信中间件 AimRT

目录 一、什么是AimRT二、AimRT与ROS22.1 定位与设计2.2 组成与通信方式对比 三、AimRT基本概念3.1 Node、Pkg 和 Module3.2 Protocol、Channel、Rpc 和 Filter3.3 App模式 和 Pkg模式3.4 Executor3.5 Plugin 一、什么是AimRT AimRT 是智元机器人公司自主研发的一款机器人通信…

SSM-Spring-AOP

目录 1 AOP实现步骤&#xff08;以前打印当前系统的时间为例&#xff09; 2 AOP工作流程 3 AOP核心概念 4 AOP配置管理 4-1 AOP切入点表达式 4-1-1 语法格式 4-1-2 通配符 4-2 AOP通知类型 五种通知类型 AOP通知获取数据 获取参数 获取返回值 获取异常 总结 5 …

idea( 2022.3.2)打包报错总结

一 报错 class lombok.javac.apt.LombokProcessor (in unnamed module 0x4fe64d23) cannot access class com.sun.tools.javac.processing.JavacProcessingEnvironment (in module jdk.compiler) because module jdk.compiler does not export com.sun.tools.javac.processing …

攻防靶场(29):目录权限和文件权限 ICMP

目录 1. 侦查 1.1 收集目标网络信息&#xff1a;IP地址 1.2 主动扫描&#xff1a;扫描IP地址段 1.3 搜索目标网站 2. 初始访问 2.1 利用面向公众的应用 3. 权限提升 3.1 有效账户&#xff1a;本地账户 3.2 滥用特权控制机制&#xff1a;Sudo和Sudo缓存 靶场下载地址&#xff1a…

C++ 面向对象编程:多态、虚函数原理

多态的通用描述便是&#xff0c;使用父类指针调用函数&#xff0c;可以根据对象类型来调用对应类型函数&#xff0c;我们分几个步骤来理解&#xff0c;先看下类的占用空间&#xff0c;然后拓展到虚函数对应数组&#xff0c;最后理解多态的原理。 我们先来看下在多态中没有任何…

王老吉药业SRM系统上线 携手隆道共启战略合作新篇章

12月27日&#xff0c;广州王老吉药业股份有限公司&#xff08;简称“王老吉药业”&#xff09;SRM项目上线启动会&#xff0c;在王老吉科普教育基地——“吉园”隆重举行。广药集团纪委主任陈耕、王老吉药业总工程师黄晓丹、隆道公司总裁吴树贵、项目经理赵耀、供应商代表郭伟及…

JavaScript基础 -- 变量、作用域与内存

1 原始值与引用值 原始值就是最简单的数据&#xff0c;引用值则是由多个值构成的对象。在把一个值赋给变量时&#xff0c;JavaScript引擎必须要确定这个值是原始值还是引用值 原始值大小固定&#xff0c;保存在栈内存上&#xff1b;引用值是对象&#xff0c;存储在堆内存上 它…

SQL—替换字符串—replace函数用法详解

SQL—替换字符串—replace函数用法详解 REPLACE() 函数——查找一个字符串中的指定子串&#xff0c;并将其替换为另一个子串。 REPLACE(str, old_substring, new_substring)str&#xff1a;要进行替换操作的原始字符串。old_substring&#xff1a;要被替换的子串。new_substri…

[极客大挑战 2019]Http 1

进入环境&#xff1a; 检查源码发现有一个链接&#xff0c;但是这里没有绑定&#xff0c;需要手动跳转&#xff0c;打开后&#xff0c;发现提示&#xff1a; 这里就是需要我们从https://Sycsecret.buuoj.cn来访问它 因此我们抓包&#xff0c;使用referer&#xff1a;服务器伪造…

吾杯网络安全技能大赛——Misc方向WP

吾杯网络安全技能大赛——Misc方向WP Sign 题目介绍: 浅浅签个到吧 解题过程&#xff1a; 57754375707B64663335376434372D333163622D343261382D616130632D3634333036333464646634617D 直接使用赛博橱子秒了 flag为 WuCup{df357d47-31cb-42a8-aa0c-6430634ddf4a} 原神启动…

如何查看下载到本地的大模型的具体大小?占了多少存储空间:Llama-3.1-8B下载到本地大概15GB

这里介绍一下tree命令&#xff0c;可以方便的查看文件目录结构和文件大小。 命令行tree的具体使用&#xff0c;请参考笔者的另一篇博客&#xff1a;深入了解 Linux tree 命令及其常用选项&#xff1a;Linux如何显示目录结构和文件大小&#xff0c;一言以蔽之&#xff0c;sudo a…

【Java回顾】Day2 正则表达式----异常处理

参考资料&#xff1a;菜鸟教程 https://www.runoob.com/java/java-exceptions.html 正则表达式 有一部分没看完 介绍 字符串的模式搜索、编辑或处理文本java.util.regex包&#xff0c;包含了pattern和mathcer类&#xff0c;用于处理正则表达式的匹配操作。 捕获组 把多个字符…

招银网路Java后端一面,难度有点大!

这是一位武汉理工大学同学的招银网络一面面经,同样附带超详细的参考答案。大家可以用来查漏补缺,针对性地补短板。 招银网络一面还是比较简单的,基本都是一些比较重要且高频的常规八股,项目问的不多。到了二面的时候, 会开始主要考察你的项目。 1、自我介绍 自我介绍一般…

xadmin后台首页增加一个导入数据按钮

xadmin后台首页增加一个导入数据按钮 效果 流程 1、在添加小组件中添加一个html页面 2、写入html代码 3、在urls.py添加导入数据路由 4、在views.py中添加响应函数html代码 <!DOCTYPE html> <html lang