当前位置: 首页 > news >正文

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 去模拟关系型复杂查询,例如联表查询、聚合查询等基本不可能,维护成本⾼。

相关文章:

8.Redis之hash类型

1.hash类型的基本介绍 哈希表[之前学过的所有数据结构中,最最重要的] 1.日常开发中,出场频率非常高. 2.面试中,非常重要的考点, Redis 自身已经是键值对结构了Redis 自身的键值对就是通过 哈希 的方式来组织的 把 key 这一层组织完成之后, 到了 value 这一层~~ value 的其中…...

Edge浏览器

微软 Edge 是由微软开发的网络浏览器,它是 Windows 10 操作系统的默认浏览器,取代了之前的 Internet Explorer。Edge 浏览器在设计上注重性能、安全性和易用性,同时也提供了许多实用的功能,如内置笔记、阅读视图、集成的语音助手等…...

springboot项目中图片上传之后需要重启工程才能看到图片?

需求背景 最近在做一个用户自定义上传头像的小需求,用户上传头像然后需要立马回显。 需求是很常见的、正当的需求。如果不使用到对象存储这类服务,我们把用户头像的图片文件仅存在本地就可以了。我们在开发的过程中为了工程管理方便通常下意识会将图片…...

打卡信奥刷题(20)用Scratch图形化工具信奥B3756 [信息与未来 2021] 幸运数字

本题的基础是进制转换,关于2进制转换可以参考打卡信奥刷题(19)用Scratch图形化工具信奥B3972 [语言月赛 202405] 二进制 题解 知道了2进制,来实现5进制、7进制、9进制是一样的。 [信息与未来 2021] 幸运数字 题目描述 如果⼀个…...

Stream流模式通信及示例

Stream流模式通信是指在计算机网络中,数据作为连续的字节流传输而不是独立的数据包。它是一种面向连接的通信方式,常见于TCP(传输控制协议)。以下是Stream流模式通信的基本概念和一个简单的示例。 基本概念 面向连接&#xff1…...

从0开始学统计-t分布

1.t分布是如何被发现的? t分布最早由英国统计学家威廉塞弗顿(William Sealy Gosset)在1908年提出。塞弗顿是爱尔兰的一名酿酒厂的统计学家,他的工作需要对小样本数据进行分析。由于当时样本量较小(通常小于30&#xf…...

Git总结超全版

最近想系统的回顾一下Git的使用,如果只想快速的集成git到idea,可以参考另一篇我的博客中的git部分 目录 版本管理工具简介Git安装与配置Git远程仓库配置 Git常用命令为常用命令配置别名(可选)Git忽略文件.gitignore一些概念*本地仓库操作删除仓库内容 *远…...

网络安全之安全协议浅谈

安全协议 安全协议概述安全协议分类IPSecIPSec安全协议IPSec架构IPSec封装模式AH协议ESP协议SET协议SET协议电子交易模型SET协议安全目标认证中心CA 安全协议概述 安全协议是信息交换安全的核心,它在网络不同层次上、针对不同应用,通过对各种密码学技术…...

华为云部署前端项目发生的事

今天刚买了一个云服务,想着部署一下前端项目: 使用的是 docker nginx 部署 部署方法,在以往的文章中有介绍,如有兴趣可以看看docker 部署; 结果发现部署成功之后,竟然无法访问,从命令来看&…...

需求:实现一个可以统计代码的运行时间

需求:有一个做加法计算的函数,要统计执行这个加法函数代码运行了多久 import timedef add(a, b):time.sleep(1)return a bst time.time() add(100, 200) et time.time() print("该函数运行时间为:", et - st) 学了闭包&#x…...

软考高级之redis中使用zset实现延迟队列,你答对了么?

实现延迟队列的思路 zset的特性,带有分数的排序,以时间戳作为分数进行排序 添加任务 zdd取出任务 zrangbyscore执行任务 zrem 定时任务 public static void main(String[] args) {Jedis jedis new Jedis("ip", 6379);TimerTask task new …...

CS 下载安装详解

目录 CS简介: CS下载地址: CS的安装: CS简介: CS为目前渗透中常用的一款工具,它的强大在于控制windows木马,CS主要控制windows木马。 CS下载地址: 链接:https://pan.baidu.com/…...

前端canvas项目实战——在线图文编辑器(十):小地图MiniMap(上)

目录 前言一、 效果展示二、 实现步骤0. 行动前的思考1. 为小地图更新「背景图」2. 为小地图更新「滑动窗口」2.1 获取新的滑动窗口「宽高」2.2 获取新的滑动窗口「位置」3. 为小地图更新「遮罩」后记前言 上一篇博文中,我们引入了「逻辑画布」的概念,让整个工具的页面看起来…...

linux的chmod的数字太难记了,用u, g, o, a更简单!

u, g, o, 和 a是用来设置或查看文件或目录权限在类Unix或Linux系统中的特殊字符,它们分别代表文件或目录的所有者(user)、所属组(group)、其他用户(others)和所有用户(all users)。 而权限方r和w是其中的两种,分别代表读权限(read&#xff0…...

牛客热题:有效括号

📟作者主页:慢热的陕西人 🌴专栏链接:力扣刷题日记 📣欢迎各位大佬👍点赞🔥关注🚓收藏,🍉留言 文章目录 牛客热题:有效括号题目链接方法一&#x…...

利用SQL语句实现多表联合查询——多表关系介绍

1.多对多查询 先创建一个student表和course表,应该利用外键来实现,通过一个中间表分别对应student和course中的id CREATE TABLE student (id INT unsigned PRIMARY KEY,name VARCHAR(255),no VARCHAR(50) ); CREATE TABLE course (id INT PRIMARY KEY,…...

Java中IO流类的体系

Java为我们提供了多种多样的IO流,我们可以根据不同的功能及性能要求挑选合适的IO流,如图所示,为Java中IO流类的体系。 从上图发现,很多流都是成对出现的,比如: FileInputStream/FileOutputStream&#xff0…...

【调试笔记-20240521-Linux-编译 QEMU/x86_64 可运行的 OpenWrt 固件】

调试笔记-系列文章目录 调试笔记-20240521-Linux-编译 QEMU/x86_64 可运行的 OpenWrt 固件 文章目录 调试笔记-系列文章目录调试笔记-20240521-Linux-编译 QEMU/x86_64 可运行的 OpenWrt 固件 前言一、调试环境操作系统:Ubuntu 22.04.4 LTS编译环境调试目标 二、调…...

GitLab的原理及应用详解(六)

本系列文章简介: 随着软件开发的不断进步和发展,版本控制系统成为了现代软件开发过程中不可或缺的一部分。而GitLab作为其中一种流行的版本控制工具,在软件开发领域享有广泛的应用。GitLab不仅提供了强大的版本控制功能,还集成了项…...

【调和级数】100321. 优质数对的总数 II

本文涉及知识点 调和级数 质数、最大公约数、菲蜀定理 LeetCode100321. 优质数对的总数 II 给你两个整数数组 nums1 和 nums2,长度分别为 n 和 m。同时给你一个正整数 k。 如果 nums1[i] 可以被 nums2[j] * k 整除,则称数对 (i, j) 为 优质数对&#…...

接口测试中缓存处理策略

在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

企业如何增强终端安全?

在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

Web中间件--tomcat学习

Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下: 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载,下载地址:https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...

前端调试HTTP状态码

1xx(信息类状态码) 这类状态码表示临时响应,需要客户端继续处理请求。 100 Continue 服务器已收到请求的初始部分,客户端应继续发送剩余部分。 2xx(成功类状态码) 表示请求已成功被服务器接收、理解并处…...

归并排序:分治思想的高效排序

目录 基本原理 流程图解 实现方法 递归实现 非递归实现 演示过程 时间复杂度 基本原理 归并排序(Merge Sort)是一种基于分治思想的排序算法,由约翰冯诺伊曼在1945年提出。其核心思想包括: 分割(Divide):将待排序数组递归地分成两个子…...

GraphRAG优化新思路-开源的ROGRAG框架

目前的如微软开源的GraphRAG的工作流程都较为复杂,难以孤立地评估各个组件的贡献,传统的检索方法在处理复杂推理任务时可能不够有效,特别是在需要理解实体间关系或多跳知识的情况下。先说结论,看完后感觉这个框架性能上不会比Grap…...

MeshGPT 笔记

[2311.15475] MeshGPT: Generating Triangle Meshes with Decoder-Only Transformers https://library.scholarcy.com/try 真正意义上的AI生成三维模型MESHGPT来袭!_哔哩哔哩_bilibili GitHub - lucidrains/meshgpt-pytorch: Implementation of MeshGPT, SOTA Me…...