Redis - Hash 哈希
一、基本认识
⼏乎所有的主流编程语⾔都提供了哈希(hash)类型,它们的叫法可能是哈希、字典、关联数 组、映射。在Redis中,哈希类型是指值本⾝⼜是⼀个键值对结构,形如key="key",value={{ field1, value1 }, ..., {fieldN, valueN } },Redis 键值对和哈希类型⼆者的关系可以⽤图2-15来表⽰。
图2-15字符串和哈希类型对⽐

哈希类型中的映射关系通常称为field-value,⽤于区分Redis整体的键值对(key-value), 注意这⾥的value是指field对应的值,不是键(key)对应的值,请注意value在不同上下 ⽂的作⽤。
二、命令
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) 1redis> HGET myhash field1"Hello"
2.2、HGET
获取hash中指定字段的值。
语法:
HGET key field
命令有效版本:2.0.0之后
时间复杂度:O(1)
返回值:字段对应的值或者nil。
⽰例:
redis> HSET myhash field1 "foo"(integer) 1redis> 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) 1redis> HEXISTS myhash field1(integer) 1redis> 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) 1redis> HDEL myhash field1(integer) 1redis> HDEL myhash field2(integer) 0
2.5、HKEYS
获取hash中的所有字段。
语法:
HKEYS key
命令有效版本:2.0.0之后
时间复杂度:O(N) , N为field的个数.
返回值:字段列表。
⽰例:
redis> HSET myhash field1 "Hello"(integer) 1redis> HSET myhash field2 "World"(integer) 1redis> HKEYS myhash1) "field1"2) "field2"
2.6、HVALS
获取hash中的所有的值。
语法:
HVALS key
命令有效版本:2.0.0之后
时间复杂度:O(N),N为field的个数.
返回值:所有的值。
⽰例:
redis> HSET myhash field1 "Hello"(integer) 1redis> HSET myhash field2 "World"(integer) 1redis> HVALS myhash1) "Hello"2) "World"
2.7、HGETALL
获取hash中的所有字段以及对应的值。
语法:
HGETALL key
命令有效版本:2.0.0之后
时间复杂度:O(N),N为field的个数.
返回值:字段和对应的值。
⽰例:
redis> HSET myhash field1 "Hello"(integer) 1redis> HSET myhash field2 "World"(integer) 1redis> HGETALL myhash1) "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) 1redis> HSET myhash field2 "World"(integer) 1redis> HMGET myhash field1 field2 nofield1) "Hello"2) "World"3) (nil)
在使⽤HGETALL时,如果哈希元素个数⽐较多,会存在阻塞Redis的可能。如果开发⼈员只 需要获取部分field,可以使⽤HMGET,如果⼀定要获取全部field,可以尝试使⽤HSCAN 命令,该命令采⽤渐进式遍历哈希类型。
2.9、HLEN
获取hash中的所有字段的个数。
语法:
HLEN key
命令有效版本:2.0.0之后
时间复杂度:O(1)
返回值:字段个数。
⽰例:
redis> HSET myhash field1 "Hello"(integer) 1redis> HSET myhash field2 "World"(integer) 1redis> 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) 1redis> HSETNX myhash field "World"(integer) 0redis> HGET myhash field"Hello"
2.11、HINCRBY
将 hash 中字段对应的数值添加指定的值。
语法:
HINCRBY key field increment
命令有效版本:2.0.0之后
时间复杂度:O(1)
返回值:该字段变化之后的值。
⽰例:
redis> HSET myhash field 5(integer) 1redis> HINCRBY myhash field 1(integer) 6redis> HINCRBY myhash field -1(integer) 5redis> 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) 1redis> HINCRBYFLOAT mykey field 0.1"10.6"redis> HINCRBYFLOAT mykey field -5"5.6"redis> HSET mykey field 5.0e3(integer) 0redis> HINCRBYFLOAT mykey field 2.0e2"5200"
2.13、命令⼩结
表 2-4 是哈希类型命令的效果、时间复杂度,开发⼈员可以参考此表,结合⾃⾝业务需求和数据 ⼤⼩选择合适的命令。
表 2-4 哈希类型命令⼩结
| 命令 | 执⾏效果 | 时间复杂度 |
|---|---|---|
| hset key field value | 设置值 | O(1) |
| hget key field | 获取值 | O(1) |
| hdel key field [field ...] | 删除 field | O(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+n | O(1) |
| hincrbyfloatkey field n | 对应 field-value+n | O(1) |
| hstrlen key field | 计算 value 的字符串⻓度 | O(1) |
三、内部编码
哈希的内部编码有两种:
- ziplist(压缩列表):当哈希类型元素个数⼩于hash-max-ziplist-entries配置(默认512个)、 同时所有值都⼩于hash-max-ziplist-value配置(默认64字节)时,Redis会使⽤ziplist作为哈 希的内部实现,ziplist使⽤更加紧凑的结构实现多个元素的连续存储,所以在节省内存⽅⾯⽐ hashtable更加优秀。
- hashtable(哈希表):当哈希类型⽆法满⾜ziplist的条件时,Redis会使⽤hashtable作为哈希 的内部实现,因为此时ziplist的读写效率会下降,⽽hashtable的读写时间复杂度为O(1)。
下⾯的⽰例演⽰了哈希类型的内部编码,以及响应的变化。
1)当field个数⽐较少且没有⼤的value时,内部编码为ziplist:
127.0.0.1:6379> hmset hashkey f1 v1 f2 v2OK127.0.0.1:6379> object encoding hashkey"ziplist"
2)当有value⼤于64字节时,内部编码会转换为hashtable:
127.0.0.1:6379> hset hashkey f3 "one string is bigger than 64 bytes ... 省略..."OK127.0.0.1:6379> object encoding hashkey"hashtable"
3)当field个数超过512时,内部编码也会转换为hashtable:
127.0.0.1:6379> hmset hashkey f1 v1 h2 v2 f3 v3 ... 省略 ... f513 v513OK127.0.0.1:6379> object encoding hashkey"hashtable"
四、使用场景
图2-16为关系型数据表记录的两条⽤⼾信息,⽤⼾的属性表现为表的列,每条⽤⼾信息表现为⾏。如果映射关系表⽰这两个⽤⼾信息,则如图2-17所⽰。
图2-16关系型数据表保存⽤⼾信息
| uid | name | age | city |
|---|---|---|---|
| 1 | James | 28 | Beijing |
| 2 | Johnathan | 30 | Xian |
图2-17映射关系表⽰⽤⼾信息

相⽐于使⽤JSON格式的字符串缓存⽤⼾信息,哈希类型变得更加直观,并且在更新操作上变得 更灵活。可以将每个⽤⼾的id定义为键后缀,多对field-value对应⽤⼾的各个属性。
但是需要注意的是哈希类型和关系型数据库有两点不同之处:
- 哈希类型是稀疏的,⽽关系型数据库是完全结构化的,例如哈希类型每个键可以有不同的field,⽽ 关系型数据库⼀旦添加新的列,所有⾏都要为其设置值,即使为null,如图2-18所⽰。
- 关系数据库可以做复杂的关系查询,⽽Redis去模拟关系型复杂查询,例如联表查询、聚合查询等 基本不可能,维护成本⾼。
图2-18关系型数据库稀疏性

五、缓存⽅式对⽐
截⾄⽬前为⽌,已经能够⽤三种⽅法缓存⽤⼾信息,下⾯给出三种⽅案的实现⽅法和优缺点 分析。
1. 原⽣字符串类型⸺使⽤字符串类型,每个属性⼀个键。
set user:1:name Jamesset user:1:age 23set user:1:city Beijing
优点:实现简单,针对个别属性变更也很灵活。
缺点:占⽤过多的键,内存占⽤量较⼤,同时⽤⼾信息在Redis中⽐较分散,缺少内聚性,所以这种 ⽅案基本没有实⽤性。
2. 序列化字符串类型,例如JSON格式
set user:1 经过序列化后的⽤⼾对象字符串
优点:针对总是以整体作为操作的信息⽐较合适,编程也简单。同时,如果序列化⽅案选择合适,内 存的使⽤效率很⾼。
缺点:本⾝序列化和反序列需要⼀定开销,同时如果总是操作个别属性则⾮常不灵活。
3. 哈希类型
hmset user:1 name James age 23 city Beijing
优点:简单、直观、灵活。尤其是针对信息的局部变更或者获取操作。
缺点:需要控制哈希在ziplist和hashtable两种内部编码的转换,可能会造成内存的较⼤消耗。
相关文章:
Redis - Hash 哈希
一、基本认识 ⼏乎所有的主流编程语⾔都提供了哈希(hash)类型,它们的叫法可能是哈希、字典、关联数 组、映射。在Redis中,哈希类型是指值本⾝⼜是⼀个键值对结构,形如key"key",value{{ field1, v…...
dns服务部署
配置主文件,编辑主配置文件设置监听IP , 重启服务:[rootlocalhost ~]# systemctl restart network 安装bind 主服务器IP信息: [rootlocalhost ~]# nmcli c modify ens160 ipv4.method manual ipv4.addresses 129.168.160.131/24…...
【Hadoop和Hbase集群配置】3台虚拟机、jdk+hadoop+hbase下载和安装、环境配置和集群测试
目录 一、环境 二、虚拟机配置 三、 JDK、Hadoop、HBase的安装和配置 【安装和配置JDK】 【安装和配置Hadoop】 【安装和配置Hbase】 四、 Hadoop和HBase集群测试 【Hadoop启动测试】 【Hbase启动测试】 一、环境 OS: CentOS-7 JDK: v1.8.0_131 Hadoop: v2.7.6 Hb…...
超萌!HTMLCSS:超萌卡通熊猫头
效果演示 创建了一个卡通风格的熊猫头 HTML <div class"box"><div class"head"><div class"head-copy"></div><div class"ears-left"></div><div class"ears-right"></di…...
人脑与机器连接:神经科技的伦理边界探讨
内容概要 在当今科技飞速发展的时代,人脑与机器连接已成为一个引人注目的前沿领域。在这一背景下,神经科技的探索为我们打开了一个全新的世界,从脑机接口到人工智能的飞跃应用,不仅加速了技术的进步,更触动了我们内心…...
Mac M1 Docker创建Rocketmq集群并接入Springboot项目
文章目录 前言Docker创建rocketmq集群创建rocketmq目录创建docker-compose.yml新增broker.conf文件启动容器 Springboot 接入 rocketmq配置maven依赖修改appplication.yml新增消息生产者新增消费者测试发送消息 总结 前言 最近公司给配置了一台mac,正好有时间给装一…...
k8s 查看cpu使用率最高的pod
在 Kubernetes 中,可以使用 kubectl top 命令查看 Pod 的资源使用情况,从而找到 CPU 使用率最高的 Pod。 步骤 使用 kubectl top pods 查看所有 Pod 的 CPU 使用情况 运行以下命令查看集群中所有 Pod 的 CPU 和内存使用情况: kubectl top po…...
jenkins 构建报错 Cannot run program “sh”
原因 在 windows 操作系统 jenkins 自动化部署的时候, 由于自动化构建的命令是 shell 执行的,而默认windows 从 path 路径拿到的 shell 没有 sh.exe ,因此报错。 解决方法 前提是已经安装过 git WINR 输入cmd 打开命令行, 然后输入where git 获取 git 的路径, …...
Netty ByteBuf 分配 | 池化复用 、直接内存
Netty ByteBuf 分配 本文主要内容关于 ByteBuf 分配介绍,为了更好的理解本文,我们可以带着几个问题思考 在IO密集型业务场景下,可能涉及大量ByteBuf分配,这时我们需 要考虑会不会产生OOM会不会出现频繁GC会不会内存泄露 根据上…...
【数据结构】堆和二叉树(2)
文章目录 前言一、建堆和堆排序1.堆排序 二、二叉树链式结构的实现1.二叉树的遍历 三、链式二叉树的功能函数1.二叉树结点个数2.二叉树叶子结点个数3.二叉树的高度4.二叉树第k层结点个数5. 二叉树查找值为x的结点6.二叉树销毁 总结 前言 接着上一篇博客,我们继续分…...
Oracle分区技术特性
Oracle 的分区是一种“分而治之”的技术,通过将大表、索引分成可以独立管理的、小的 Segment,从而避免了对每个对象作为一个大的、单独的 Segment 进行管理,为海量数据访问提供了可伸缩的性能。自从 Oracle 引入分区技术以来,Orac…...
Hive操作库、操作表及数据仓库的简单介绍
数据仓库和数据库 数据库和数仓区别 数据库与数据仓库的区别实际讲的是OLTP与OLAP的区别 操作型处理(数据库),叫联机事务处理OLTP(On-Line Transaction Processing),也可以称面向用户交易的处理系统,它是针对具体业务…...
智能网联汽车:人工智能与汽车行业的深度融合
内容概要 在这个快速发展的时代,智能网联汽车已经不再是科幻电影的专利,它正在悄然走进我们的日常生活。如今,人工智能(AI)技术与汽车行业的结合犹如一场科技盛宴,让我们看到了未来出行的新方向。通过自动…...
VUE 循环的使用方法集锦
vue---循环方式以及跳出循环 在做VUE项目开发过程中,数据循环是常见的操作方式,以下是几种常见的数据循环方式: 一、for循环 let data [1,2,3,4,5,6,7,8,9,10]; for(let i0; i<data.length; i){console.log(data[i]);if(i>5){break;…...
Centos部署资料
1. 离线rpm 1.1 下载地址: 阿里云rpmfind 1.2 本地安装: [rootlocalhost ~]# yum localinstall unzip-6.0-21.el7.x86_64.rpm2. 服务器操作 2.1 修改网络ip [rootlocalhost ~]# cd /etc/sysconfig/network-scripts/ [rootlocalhost network-script…...
AI之硬件对比:据传英伟达Nvidia2025年将推出RTX 5090-32GB/RTX 5080-24GB、华为2025年推出910C/910D
AI之硬件对比:据传英伟达Nvidia2025年将推出RTX 5090-32GB/RTX 5080-24GB、华为2025年推出910C/910D 目录 Nvidia的显卡 Nvidia的5090/5080/4090/4080:据传传英伟达Nvidia RTX 5090后续推出32GB版且RTX 5080后续或推出24GB版 RTX 5090相较于RTX 4090&…...
其他节点使用kubectl访问集群,kubeconfig配置文件 详解
上述两种方式:可使用kubectl连接k8s集群。 $HOME/.kube/config 是config文件默认路径,要么直接定义环境变量,要么就直接把文件拷过去 config文件里面,定义了context,里面指定了用户和对应的集群信息: ku…...
【鉴权】深入解析OAuth 2.0:访问令牌与刷新令牌的安全管理
目录 引言一、访问令牌(Access Token)1.1 访问令牌概述1.2 访问令牌的格式1.2.1 JWT(JSON Web Token)1.2.1.1 JWT 结构1.2.1.2 示例 JWT 1.2.2 Bearer Token 1.3 访问令牌的有效期1.4 访问令牌的工作流程 二、刷新令牌(…...
【AI视频换脸整合包及教程】AI换脸新星:Rope——让换脸变得如此简单
在数字技术迅猛发展的今天,人工智能(AI)的应用已经渗透到了我们生活的方方面面,从日常的语音助手到复杂的图像处理,无不体现着AI技术的魅力。特别是在娱乐和创意领域,AI技术更是展现出了惊人的潜力。其中&a…...
限界上下文(Bounded Context)
限界上下文(Bounded Context):领域驱动设计中的重要概念 在领域驱动设计(Domain-Driven Design, DDD)中,限界上下文(Bounded Context)是一个非常重要的概念。限界上下文定义了一个特定领域模型的边界,确保在这个边界内,领域模型的术语、规则和逻辑是一致的。通过明确…...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
