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)是一个非常重要的概念。限界上下文定义了一个特定领域模型的边界,确保在这个边界内,领域模型的术语、规则和逻辑是一致的。通过明确…...

使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...

linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...

微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...

莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...