Redis Hash数据类型

Redis Hash数据类型

几乎所有的主流编程语言都提供了哈希(hash)类型,它们的叫法可能是哈希、字典、关联数组、映射。在 Redis 中,哈希类型是指值本身又是一个键值对结构,形如key = “key”,value = {ffield1, value1 }, … {fieldN, valueN } },Redis 键值对和哈希类型二者的关系可以用下图来表示。

字符串和哈希类型对比:

在这里插入图片描述

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

命令

hset和hget

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

语法

HSET key field value [field value ...]

时间复杂度:插入一组 field 为 O(1),插入 N 组 field 为 O(N)

返回值:添加的字段的个数。 如果当前字段已经存在,此时hset相当于更新,则返回0

示例

redis> hset myhash field1 "Hello"
(integer) 1
redis> hget myhash field1
"Hello"redis> hset myhash field1 hello field2 world
(integer) 2

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

语法

HGET key field

时间复杂度:O(1)

返回值:字段对应的值或者nilo

示例:

redis> hset myhash field1 "foo"
(integer) 1
redis> hget myhash field1
"foo"
redis> hget myhash field2
(nil)

hexists

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

语法

HEXISTS key field

时间复杂度:O(1)

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

示例

redis> hset myhash field1 "foo"
(integer) 1
redis> hexists myhash field1
(integer) 1
redis> hexists myhash field2
(integer) 0

hdel

删除hash中指定的字段。

语法

HDEL key field [field ...]

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

返回值:本次操作删除的字段个数。

示例

redis> hset myhash field1 "foo"
(integer) 1
redis> hdel myhash field1
(integer) 1
redis> hexists myhash filed
(integer) 0
redis> hdel myhash field2
(integer) 0

hkeys

获取hash中的所有字段。

语法

HKEYS key

时间复杂度: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"

hvals

获取hash中的所有的值。

语法

HVALS key

时间复杂度: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"

hgetall

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

语法

HGETALL key

时间复杂度: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"

hmget

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

语法

HMGET key field [field ...]

时间复杂度:只查询⼀个元素为 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 命令,该命令采用渐进式遍历哈希类型。

hlen

获取 hash 中的所有字段(key)的个数。

语法

HLEN key

时间复杂度:O(1)

返回值:字段个数。

示例

redis> hset myhash field1 "Hello"
(integer) 1
redis> hset myhash field2 "World"
(integer) 1
redis> hlen myhash
(integer) 2

hsetnx

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

语法

HSETNX key field value

时间复杂度:O(1)

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

示例

redis> hsetnx myhash field "Hello"
(integer) 1
redis> hsetnx myhash field "World"
(integer) 0
redis> hget myhash field
"Hello"

hincrby

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

语法

HINCRBY key field increment

时间复杂度: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

hincrbyfloat

hincrby的浮点数版本。

语法:

HINCRBYFLOAT key field increment

时间复杂度: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   #5000
(integer) 0
redis> HINCRBYFLOAT mykey field 2.0e2   #200
"5200"

内部编码

哈希的内部编码有两种:

  • 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 v2
OK
127.0.0.1:6379> object encoding hashkey
"ziplist"

2)当有 value 大于 64 字节时,内部编码会转换为 hashtable:

127.0.0.1:6379> hset hashkey f3 6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666
(integer) 1
127.0.0.1:6379> object encoding hashkey
"hashtable"

3)当 field 个数超过 512 时,内部编码也会转换为 hashtable

127.0.0.1:6379> hmset hashkey f1 v1 f2 v2 f3 v3 ... 省略 ... f513 v513
OK
127.0.0.1:6379> object encoding hashkey
"hashtable"

使用场景

图"关系型数据表保存用户信息"为关系型数据表记录的两条用户信息,用户的属性表现为表的列,每条用户信息表现为行。如果映射关系表示这两个用户信息,则如图"映射关系表示用户信息"所示。

关系型数据表保存用户信息

在这里插入图片描述

映射关系表示用户信息

在这里插入图片描述

相比于使用Json格式的字符串缓存用户信息,哈希类型变得更加直观,并且在更新操作上变得更灵活。可以将每个用户的id定义为键后缀,多对field-value对应用户的各个属性,类似如下伪代码:

UserInfo getUserInfo(long uid) {// 根据 uid 得到 Redis 的键String key = "user:" + uid;// 尝试从 Redis 中获取对应的值userInfoMap = Redis 执⾏命令:hgetall key;// 如果缓存命中(hit)if (value != null) {// 将映射关系还原为对象形式UserInfo userInfo = 利⽤映射关系构建对象(userInfoMap);return userInfo;}// 如果缓存未命中(miss)// 从数据库中,根据 uid 获取⽤⼾信息UserInfo userInfo = MySQL 执⾏ SQL:select *from user_info where uid = <uid>// 如果表中没有 uid 对应的⽤⼾信息if (userInfo == null) {响应 404 return null;}// 将缓存以哈希类型保存Redis 执⾏命令:hmset key name userInfo.name age userInfo.age city userInfo.c// 写⼊缓存,为了防⽌数据腐烂(rot),设置过期时间为 1 ⼩时(3600 秒)Redis 执⾏命令:expire key 3600// 返回⽤⼾信息return userInfo;
}

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

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

缓存方式对比

  1. 原生字符串类型⸺使用字符串类型,每个属性⼀个键。
set user:1:name James
set user:1:age 23
set user:1:city Beijing
  • 优点:实现简单,针对个别属性变更也很灵活。
  • 缺点∶占用过多的键,内存占用量较大,同时用户信息在Redis中比较分散,缺少内聚性,所以这种方案基本没有实用性。
  1. 序列化字符串类型,例如 JSON 格式
set user:1 经过序列化后的⽤⼾对象字符串
  • 优点∶针对总是以整体作为操作的信息比较合适,编程也简单。同时,如果序列化方案选择合适,内存的使用效率很高。
  • 缺点:本身序列化和反序列需要一定开销,同时如果总是操作个别属性则非常不灵活。
  1. 哈希类型
hmset user:1 name James age 23 city Beijing
  • 优点:简单、直观、灵活。尤其是针对信息的局部变更或者获取操作。
set user:1:name James
set user:1:age 23
set user:1:city Beijing
  • 优点:实现简单,针对个别属性变更也很灵活。
  • 缺点∶占用过多的键,内存占用量较大,同时用户信息在Redis中比较分散,缺少内聚性,所以这种方案基本没有实用性。
  1. 序列化字符串类型,例如 JSON 格式
set user:1 经过序列化后的⽤⼾对象字符串
  • 优点∶针对总是以整体作为操作的信息比较合适,编程也简单。同时,如果序列化方案选择合适,内存的使用效率很高。
  • 缺点:本身序列化和反序列需要一定开销,同时如果总是操作个别属性则非常不灵活。
  1. 哈希类型
hmset user:1 name James age 23 city Beijing
  • 优点:简单、直观、灵活。尤其是针对信息的局部变更或者获取操作。
  • 缺点:需要控制哈希在ziplist和 hashtable两种内部编码的转换,可能会造成内存的较大消耗。

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

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

相关文章

LoadBalancer将服务暴露到外部实现负载均衡purelb-layer2模式配置介绍

目录 一.purelb简介 1.简介 2.purelb的layer2工作模式特点 二.layer2的配置演示 1.首先准备ipvs和arp配置环境 2.purelb部署开始 &#xff08;1&#xff09;下载purelb-complete.yaml文件并应用 &#xff08;2&#xff09;查看该有的资源是否创建完成并运行 &#xff…

GCN,GraphSAGE 到底在训练什么呢?

根据DGL 来做的&#xff0c;按照DGL 实现来讲述 1. GCN Cora 训练代码&#xff1a; import osos.environ["DGLBACKEND"] "pytorch" import dgl import dgl.data import torch import torch.nn as nn import torch.nn.functional as F from dgl.nn.pytorc…

Linux系统安装Python3环境

1、默认情况下&#xff0c;Linux会自带安装Python&#xff0c;可以运行python --version命令查看&#xff0c;如图&#xff1a; 我们看到Linux中已经自带了Python2.7.5。再次运行python命令后就可以使用python命令窗口了&#xff08;CtrlD退出python命令窗口&#xff09;。 2…

数据结构——二叉树(相关术语、性质、遍历过程)

遍历操作 二叉树的层次遍历-CSDN博客 二叉树的基本操作-CSDN博客 二叉树的先序遍历非递归实现-CSDN博客 后序遍历的非递归方式实现-CSDN博客 二叉树&#xff1a;已知先序中序求后序或者其他&#xff08;秒解&#xff09;-CSDN博客 因为之前发过一遍&#xff0c;我就不复制…

MES物料的动态批次管理漫谈

在制造企业中&#xff0c;原辅材料占产品制造总成本基本在60%以上&#xff0c;特殊材料加工企业可能达到80%以上&#xff0c;按“2/8管理原则”管理好物料就基本做好制造企业的成本管理&#xff0c;这也许是很多企业向“数字化转型”的一个主要原因&#xff0c;希望借助数字信息…

智能指针与动态内存

动态内存 new placement new 是 C 中的一种内存分配方式&#xff0c;它允许在给定的内存地址上构造对象&#xff0c;而不是在默认的堆上分配新的内存。这对于某些特殊的内存管理场景非常有用&#xff0c;例如在特定的内存池中分配对象。 C11 引入了 "new auto" 语法…

LiveGBS流媒体平台GB/T28181功能-概览中负载信息直播、回放、播放、录像、H265、级联查看负载会话列表

LiveGBS常见问题-概览中负载信息具体表示什么直播、回放、播放、录像、H265、级联等 1、负载信息2、负载信息说明3、会话列表查看3.1、会话列表 4、搭建GB28181视频直播平台 1、负载信息 实时展示直播、回放、播放、录像、H265、级联等使用数目 2、负载信息说明 直播&#x…

4.grid_sample理解与使用

pytorch中的grid_sample 文章目录 pytorch中的grid_samplegrid_samplegrid_sample函数原型实例 欢迎访问个人网络日志&#x1f339;&#x1f339;知行空间&#x1f339;&#x1f339; grid_sample 直译为网格采样&#xff0c;给定一个mask patch&#xff0c;根据在目标图像上的…

Http和WebSocket

客户端发送一次http请求&#xff0c;服务器返回一次http响应。 问题&#xff1a;如何在客户端没有发送请求的情况下&#xff0c;返回服务端的响应&#xff0c;网页可以得服务器数据&#xff1f; 1&#xff1a;http定时轮询 客户端定时发送http请求&#xff0c;eg&#…

2023经典软件测试面试题

1、问&#xff1a;你在测试中发现了一个bug&#xff0c;但是开发经理认为这不是一个bug&#xff0c;你应该怎样解决&#xff1f; 首先&#xff0c;将问题提交到缺陷管理库里面进行备案。 然后&#xff0c;要获取判断的依据和标准&#xff1a; 根据需求说明书、产品说明、设计…

AI浪潮下,非科班出身还有机会入行程序开发领域么?

前言 随着人工智能技术的快速发展和广泛应用&#xff0c;程序开发领域正迎来前所未有的挑战和机遇。但是对于非科班出身的个人而言&#xff0c;是否还有机会进入这个充满竞争的行业&#xff0c;成为一名程序员&#xff1f;那么本文就来聊聊AI浪潮下&#xff0c;分析当前程序员就…

整数和浮点数在内存中的存储

文章目录 每日一言整数在内存中的存储方式浮点数在内存中的存储结语 每日一言 You just can’t beat the person who never gives up. 你无法打败那位永不放弃的人。 整数在内存中的存储方式 整数在内存中的存储方式通常采用二进制形式&#xff0c;即将整数的数值转化为二进制…

ubuntu16.04升级openssl

Ubuntu16.04 默认带的openssl版本为1.0.2 查看&#xff1a;openssl version 1.下载openssl wget https://www.openssl.org/source/openssl-1.1.1.tar.gz 编译安装 tar xvf openssl-1.1.1.tar.gz cd openssl-1.1.1 ./config make sudo make install sudo ldconfig 删除旧版本 su…

XXL-Job详解(五):动态添加、启动任务

目录 前言XXL-Job API接口添加任务API动态添加任务动态启动任务 前言 看该文章之前&#xff0c;最好看一下之前的文章&#xff0c;比较方便我们理解 XXL-Job详解&#xff08;一&#xff09;&#xff1a;组件架构 XXL-Job详解&#xff08;二&#xff09;&#xff1a;安装部署 X…

沐风老师3DMAX随机变换工具RandomTransform插件使用方法详解

3DMAX随机变换工具RandomTransform插件使用方法 3dMax随机变换工具RandomTransform&#xff0c;是一款用MAXScript脚本语言开发的3dsMax小工具&#xff0c;可以随机变换选中的单个或多个对象的位置、角度及大小。 在3dMax中“变换”工具是最常用的工具&#xff08;移动、旋转和…

vue3+ts项目中导入组件时报错has no default export

下面这句会报错has no default export import Button from "./components/Button.vue";使用vetur这个插件&#xff08;我目前的版本是0.37.3&#xff0c;应该是这个版本之前的都不支持&#xff09;。但是依旧报错&#xff0c;所以我选择禁用了&#xff0c;就不报错了…

selenium自动化测试实战案例

Chrome DevTools 简介 Chrome DevTools 是一组直接内置在基于 Chromium 的浏览器&#xff08;如 Chrome、Opera 和 Microsoft Edge&#xff09;中的工具&#xff0c;用于帮助开发人员调试和研究网站。 借助 Chrome DevTools&#xff0c;开发人员可以更深入地访问网站&#xf…

8.4 Windows驱动开发:文件微过滤驱动入门

MiniFilter 微过滤驱动是相对于SFilter传统过滤驱动而言的&#xff0c;传统文件过滤驱动相对来说较为复杂&#xff0c;且接口不清晰并不符合快速开发的需求&#xff0c;为了解决复杂的开发问题&#xff0c;微过滤驱动就此诞生&#xff0c;微过滤驱动在编写时更简单&#xff0c;…

全网最牛最“刑”的Fiddler移动端抓包

本篇文章&#xff0c;博主想使用通俗易懂的话语&#xff0c;让大家明白以下内容&#xff1a; 什么是抓包哪些场景需要用到抓包Fiddler抓包的原理怎样使用Fiddler进行移动端抓包 抓包 包 (Packet) 是TCP/IP协议通信传输中的数据单位&#xff0c;一般也称“数据包”。 我们平常…

无人机智慧工地:助力工地管理的未来之选

在现代工地管理中&#xff0c;无人机凭借其小巧、轻便和多角度拍摄等特点得到广泛应用&#xff0c;尤其在智慧工地的现场管理中发挥着重要作用。 一、无人机代替人工巡检省时省力 以往&#xff0c;施工现场检查主要依赖人工巡检方式&#xff0c;需要较长时间。而现在&#xff…