8.Redis之hash类型

1.hash类型的基本介绍

哈希表[之前学过的所有数据结构中,最最重要的]

1.日常开发中,出场频率非常高.

2.面试中,非常重要的考点,

Redis 自身已经是键值对结构了Redis 自身的键值对就是通过 哈希 的方式来组织的
把 key 这一层组织完成之后, 到了 value 这一层~~ value 的其中一种类型还可以再是 哈希

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

2.hash命令

2.1 hset

设置 hash 中指定的字段(field)的值(value)。
HSET key field value [field value ...]
命令有效版本:2.0.0 之后
时间复杂度:插⼊⼀组 field 为 O(1), 插⼊ N 组 field 为 O(N)
返回值:添加的字段的个数。
redis> HSET myhash field1 "Hello"
(integer) 1
redis> HGET myhash field1
"Hello"

2.2 hget 

获取 hash 中指定字段的值。
语法:
HGET key field
命令有效版本:2.0.0 之后
时间复杂度:O(1)
返回值:字段对应的值或者 nil。
⽰例:
redis> HSET myhash field1 "foo"
(integer) 1
redis> HGET myhash field1
"foo"
redis> HGET myhash field2
(nil)

2.3 HEXISTS

判断 hash 中是否有指定的字段。
HEXISTS key field

命令有效版本:2.0.0 之后

时间复杂度:O(1)
返回值:1 表⽰存在,0 表⽰不存在。
⽰例:

 redis> HSET myhash field1 "foo"

(integer) 1
redis> HEXISTS myhash field1
(integer) 1
redis> HEXISTS myhash field2
(integer) 0

2.4 HDEL

删除 hash 中指定的字段。
语法:
HDEL key field [field ...]
命令有效版本:2.0.0 之后
时间复杂度:删除⼀个元素为 O(1). 删除 N 个元素为 O(N).
返回值:本次操作删除的字段个数。
⽰例:
redis> HSET myhash field1 "foo"
(integer) 1
redis> HDEL myhash field1
(integer) 1
redis> HDEL myhash field2
(integer) 0
  • del 删除的是 key
  • hdel 删除的是 field 

2.5 HKEYS

获取 hash 中的所有字段。

语法:
HKEYS key
命令有效版本:2.0.0 之后
时间复杂度:O(N), N 为 field 的个数.
返回值:字段列表。

 redis> HSET myhash field1 "Hello"

(integer) 1
redis> HSET myhash field2 "World"
(integer) 1
redis> HKEYS myhash
1) "field1"
2) "field2"

 2.6 HVALS

获取 hash 中的所有的值。
语法:
HVALS key
命令有效版本:2.0.0 之后
时间复杂度:O(N), N 为 field 的个数.
返回值:所有的值。
redis> HSET myhash field1 "Hello"
(integer) 1
redis> HSET myhash field2 "World"
(integer) 1
redis> HVALS myhash
1) "Hello"
2) "World"

2.7 HGETALL

获取 hash 中的所有字段以及对应的值。
语法:
HGETALL key
命令有效版本:2.0.0 之后
时间复杂度:O(N), N 为 field 的个数.
返回值:字段和对应的值。
redis> HSET myhash field1 "Hello"
(integer) 1
redis> HSET myhash field2 "World"
(integer) 1
redis> HGETALL myhash
1) "field1"
2) "Hello"
3) "field2"
4) "World"

2.8 HMGET

⼀次获取 hash 中多个字段的值。
语法:
HMGET key field [field ...]
命令有效版本:2.0.0 之后
时间复杂度:只查询⼀个元素为 O(1), 查询多个元素为 O(N), N 为查询元素个数.
返回值:字段对应的值或者 nil。
⽰例:
redis> HSET myhash field1 "Hello"

(integer) 1
redis> HSET myhash field2 "World"
(integer) 1
redis> HMGET myhash field1 field2 nofield
1) "Hello"
2) "World"
3) (nil)
在使⽤ HGETALL 时,如果哈希元素个数⽐较多,会存在阻塞 Redis 的可能。如果开发⼈员只 需要获取部分 field,可以使⽤ HMGET,如果⼀定要获取全部 field,可以尝试使⽤ HSCAN命令,该命令采⽤渐进式遍历哈希类型。
【敲一次命令,遍历一小部分.
再敲一次,再遍历一小部分
时间就是可控的~~
化整为零

ConcurrentHashMap(线程安全的 哈希表)

这个哈希表在扩容的时候,也是按照化整为零的方式进行的!!
Java 标准库直接提供了一些线程安全的 集合类
(Java 中也有"容器"这样的术语,指的是别的了)

2.9 HLEN

获取 hash 中的所有字段的个数。
HLEN key
命令有效版本:2.0.0 之后
时间复杂度:O(1)
返回值:字段个数。

示例 

redis> HSET myhash field1 "Hello"
(integer) 1
redis> HSET myhash field2 "World"
(integer) 1
redis> HLEN myhash
(integer) 2

2.10 HSETNX

在字段不存在的情况下,设置 hash 中的字段和值。
语法:
HSETNX key field value
命令有效版本:2.0.0 之后
时间复杂度:O(1)
返回值:1 表⽰设置成功,0 表⽰失败。
示例:
redis> HSETNX myhash field "Hello"
(integer) 1
redis> HSETNX myhash field "World"
(integer) 0
redis> HGET myhash field
"Hello"

2.11 HINCRBY

将 hash 中字段对应的数值添加指定的值。
语法:
HINCRBY key field increment
命令有效版本:2.0.0 之后
时间复杂度:O(1)
返回值:该字段变化之后的值。
示例:
redis> HSET myhash field 5
(integer) 1
redis> HINCRBY myhash field 1
(integer) 6
redis> HINCRBY myhash field -1
(integer) 5
redis> HINCRBY myhash field -10
(integer) -5

2.12 HINCRBYFLOAT

HINCRBY 的浮点数版本。
语法:
HINCRBYFLOAT key field increment
命令有效版本:2.6.0 之后
时间复杂度:O(1)
返回值:该字段变化之后的值。
示例:
redis> HSET mykey field 10.50
(integer) 1
redis> HINCRBYFLOAT mykey field 0.1
"10.6"
redis> HINCRBYFLOAT mykey field -5
"5.6"
redis> HSET mykey field 5.0e3
(integer) 0
redis> HINCRBYFLOAT mykey field 2.0e2
"5200"  

 3.命令小节

命令执⾏效果时间复杂度
hset key field value设置值O(1)
hget key field获取值O(1)
hdel key field [field ...]删除 fieldO(k), k 是 field个数
hlen key计算 field 个数O(1)
hgetall key获取所有的 field-value
O(k), k 是 field个数
hmget field [field ...]批量获取 field-value
O(k), k 是 field个数
hmset field value [field
value ...]
批量获取 field-value
O(k), k 是 field个数
hexists key field判断 field 是否存在O(1)
hkeys key获取所有的 field
O(k), k 是 field个数
hvals key
获取所有的 value
O(k), k 是 field个数
hsetnx key field value设置值,但必须在 field 不存在时才能设置成功O(1)
hincrby key field n对应 field-value +nO(1)
hincrbyfloat key field n对应 field-value +nO(1)
hstrlen key field
计算 value 的字符串⻓度
O(1)

 4.hash编码方式

压缩:rar, zip, gzip,7....

一些具体的压缩算法~~

压缩的本质,是针对数据进行重新编码.

不同的数据,有不同的特点.结合这些特点,进行精妙的设计重新编码之后,就能够缩小体积~

哈希的内部编码有两种:
ziplist(压缩列表):当哈希类型元素个数⼩于 hash-max-ziplist-entries 配置(默认 512 个)、 同时所有值都⼩于 hash-max-ziplist-value 配置(默认 64 字节)时,Redis 会使⽤ ziplist 作为哈希的内部实现,ziplist 使⽤更加紧凑的结构实现多个元素的连续存储,所以在节省内存⽅⾯⽐hashtable 更加优秀。 (内部的数据结构更加精妙)
hashtable(哈希表):当哈希类型⽆法满⾜ ziplist 的条件时,Redis 会使⽤ hashtable 作为哈希的内部实现,因为此时 ziplist 的读写效率会下降,⽽ hashtable 的读写时间复杂度为 O(1)。

ziplist 也是同理~~
内部的数据结构也是精心设计的~~
【目的节省内存空间.】
表示一个普通的hash表,可能会浪费一定的空间~~(hash 首先是一个数组~~,数组上有些位置有元素,有些没有元素)
ziplist 付出的代价,进行读写元素,速度是比较慢的,如果元素个数少,慢的并不明显, 如果元素个数太多了,慢就会雪上加霜,
如果,
1.哈希中的元素个数比较少,使用 ziplist 表示.元素个数比较多,使用 hashtable 来表示

2.每个 value 的值长度都比较短,使用 ziplist 表示.如果某个 value 的长度太长了,也会转换成 hashtable

  • hash-max-ziplist-entries 配置(默认 512 个)
  • hash-max-ziplist-value 配置(默认 64 字节)
  • 这个配置项就是可以写到 redis.conf 文件中的~~ 

5.hash的应用 

5.1 作为缓存

string 也是可以作为缓存使用的.

存储结构化的数据(类似于 数据库 表 这样的结构~~),使用 hash 类型更合适一些~~

上述场景使用 string 类型也能做到,
就需要使用到 json 这样的数据格式

  • 如果使用 string(ison)的格式来表示 Userlnfo万一只想获取其中的某个 field, 或者修改某个 field ~~就需要把整个 json 都读出来, 解析成 对象,操作 field,再重写转成 json 字符串,再写回去~~
  • 如果使用 hash 的方式来表示 Userlnfo,就可以使用 field 表示对象的每个属性(数据表的每个列)此时就可以非常方便的修改/获取任何一个属性的值了~~
  • 使用 hash 的方式,确实读写 field 更直观高效,但是付出的是空间的代价~~需要控制哈希在 ziplist 和hashtable 两种内部编码的转换,可能会造成内存的较大消耗。

高内聚

把有关联的东西放在一起,最好能放在指定的地方~~

耦合 

  • 两个模块/代码 之间的关联关系,关联关系越大,越容易相互影响认为是耦合越大~~
  • 追求的是"低耦合,避免"牵一发动全身"这边一改出 bug,影响到了其他的地方

哈希类型和关系型数据库有两点不同之处:

哈希类型是稀疏的,而关系型数据库是完全结构化的,例如哈希类型每个键可以有不同的 field,而关系型数据库⼀旦添加新的列,所有⾏都要为其设置值,即使为 null【稀疏更加节省空间】
关系数据库可以做复杂的关系查询,⽽ Redis 去模拟关系型复杂查询,例如联表查询、聚合查询等基本不可能,维护成本⾼。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

掌握ASPICE标准:汽车软件测试工程师的专业发展路径

掌握ASPICE标准:汽车软件测试工程师的专业发展路径 文:领测老贺 随着新能源汽车在中国的蓬勃发展,智能驾驶技术的兴起,汽车测试工程师的角色变得愈发关键。这一变革带来了前所未有的挑战和机遇,要求测试工程师不仅要具…

1.int 与 Integer 的简单区别

蓝桥杯刷题从此开始: 第一题就是两个数的和,个人看来主要考察 int与integer 的区别; 这是我提交的答案,竟然会报错: import java.util.*; //输入A、B,输出AB。 class add {public static void main(String …

实验一:通过路由器实现内外网互联

通过路由器实现内外网互联 一、实验拓扑 相关配置详见下图,内网区域为AR2以内设备,外网区域以AR1和PC1代替进行实验测试。 二、实验要求 通过路由器实现内外网互联: 1.各内网PC可自动获取ip地址; 2.各内网PC可ping通外网PC&…

知能行——考研数学利器

知能行使用体验全记录 首先,我先介绍一下自己,我是2018级的,2022年6月毕业,本科沈阳工业大学(双非),今年二战,专业课自动控制原理,数二英二,目标是江南大学控…

Sentinel Dashboard 规则联动持久化方案

一、Sentinel Dashboard 规则联动持久化方案 Sentinel 是阿里开源的一个流量控制组件,它提供了一种流量控制、熔断降级、系统负载保护等功能的解决方案。并且我们通过 Sentinel Dashboard 可以非常便捷的添加或修改规则策略,但是如果细心的小伙伴应该可…

redis6.2.7安装

1、下载上传到服务器 从官下载redis,地址 https://redis.io/download/#redis-downloads 然后上传到服务器目录 app/apps目录下 2、安装gcc编译器 使用gcc --version命令测试是否已经安装了gcc编译环境,如果没有安装执行以下命令安装 yum install -y …

定积分求解过程是否变限问题 以及当换元时注意事项

目录 定积分求解过程是否变限问题 文字理解: 实例理解: 易错点和易混点: 1:定积分中的换元指什么? 2: 不定积分中第一类换元法和第二类换元法的本质和区别 3: df(x) ----> df(x)这…

c++(一)

c&#xff08;一&#xff09; C与C有什么区别命名空间使用 输入输出流引用指针和引用的区别定义拓展 函数重载例子测试函数重载原理 参数默认值什么是参数默认值注意 在c中如何引入c的库动态内存分配new、delete与malloc、free的区别&#xff1f; C与C有什么区别 <1>都是…

【高数】重点内容,公式+推导+例题,大学考试必看

目录 1 隐函数求导1.1 公式1.2 说明1.3 例题 2 无条件极值2.1 运用2.2 求解2.3 例题 3 条件极值3.1 运用3.2 求解3.3 例题 4 二重积分4.1 直角坐标下4.2 极坐标下4.3 例题 5 曲线积分5.1 第一型曲线积分5.2 第二型曲线积分5.3 例题 6 格林公式6.1 公式6.2 说明6.3 例题 &#x…

C++课程设计:学校人员信息管理系统(可视化界面)

目录 学校人员信息管理系统 操作演示 MP4转GIF动图 设计功能要求 评分标准 QT Creator安装和新建项目 QT安装 QT新建项目 管理系统程序设计 mainwindow.h 文件 mainwindow.h 程序释义 mainwindow.cpp 文件 mainwindow.cpp 程序释义 main.h 文件 TXT文件生成 博主…

Java进阶学习笔记12——final、常量

final关键字&#xff1a; final是最终的意思。可以修饰类、方法、变量。 修饰类&#xff1a;该类就被称为最终类&#xff0c;特点是不能被继承了。 修饰方法&#xff1a;该方法是最终方法&#xff0c;特点是不能被重写了。 修饰变量&#xff1a;该变量只能被赋值一次。 有些…

[书生·浦语大模型实战营]——第三节:茴香豆:搭建你的 RAG 智能助理

0.RAG 概述 定义&#xff1a;RAG&#xff08;Retrieval Augmented Generation&#xff09;技术&#xff0c;通过检索与用户输入相关的信息片段&#xff0c;并结合外部知识库来生成更准确、更丰富的回答。解决 LLMs 在处理知识密集型任务时可能遇到的挑战, 如幻觉、知识过时和缺…

栈的实现(C语言)

文章目录 前言1.栈的概念及结构2.栈的实现3.具体操作3.1.初始化栈(StackInit)和销毁栈(StackDestory)3.2.入栈(StackPush)和出栈(StackPop)3.3.获得栈的个数(StackSize)、获得栈顶元素(StackTop)以及判空(StackEmpty) 前言 前段时间我们学习过了链表和顺序表等相关操作&#x…

【全网最全】2024电工杯数学建模A题54页A题保奖成品论文+配套代码

您的点赞收藏是我继续更新的最大动力&#xff01; 一定要点击如下的卡片链接&#xff0c;那是获取资料的入口&#xff01; 【全网最全】2024电工杯数学建模A题成品论文前三题完整解答matlabpy代码等&#xff08;后续会更新成品论文&#xff09;「首先来看看目前已有的资料&am…

《Ai学习笔记》自然语言处理 (Natural Language Processing):机器阅读理解-基础概念解析01

自然语言处理 (Natural Language Processing)&#xff1a; NLP四大基本任务 序列标注&#xff1a; 分词、词性标注 分类任务&#xff1a; 文本分类、情感分析 句子关系&#xff1a;问答系统、对话系统 生成任务&#xff1a;机器翻译、文章摘要 机器阅读理解的定义 Machi…

用LabVIEW进行CAN通信开发流程

本文详细介绍了在LabVIEW中开发CAN&#xff08;Controller Area Network&#xff09;通信的流程&#xff0c;包括硬件配置、软件编程和调试步骤。重点讨论了开发过程中需要注意的问题&#xff0c;如节点配置、数据帧格式和错误处理等&#xff0c;为开发高效可靠的CAN通信应用提…

[C++]debug介绍+debug时如何查看指针指向内存处的值

一、简介 预备工具和知识&#xff1a;使用使用VSCode使用Debug。 本文简介&#xff1a;本文将简要介绍debug中Continue&#xff0c;Step Over&#xff0c;Step Into和Restart的功能。并介绍如何在debug时查看动态内存地址&#xff08;指针&#xff09;的值&#xff1b; 二、D…

npm 错误,ERESOLVE unable to resolve dependency tree

npm 错误,ERESOLVE unable to resolve dependency tree 在命令中增加 --legacy-peer-dep 选项或者–force npm install --legacy-peer-depsnpm install --force

Mysql 找出未提交事务的SQL及死锁

未提交事务&#xff1a; 通过查看information_schema.INNODB_TRX视图,您可以了解当前系统中正在运行的事务情况,从而进行问题排查和性能优化。 SELECT * FROM information_schema.innodb_trx; 通过trx_state为RUNNIG,trx_started判断是否有一直RUNNING的事务。 如果有未提交…

MySQL 8.4.0 LTS 变更解析:I_S 表、权限、关键字和客户端

↑ 关注“少安事务所”公众号&#xff0c;欢迎⭐收藏&#xff0c;不错过精彩内容~ MySQL 8.4.0 LTS 已经发布 &#xff0c;作为发版模型变更后的第一个长期支持版本&#xff0c;注定要承担未来生产环境的重任&#xff0c;那么这个版本都有哪些新特性、变更&#xff0c;接下来少…