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
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
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
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
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
- del 删除的是 key
- hdel 删除的是 field
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
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
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
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命令,该命令采⽤渐进式遍历哈希类型。【敲一次命令,遍历一小部分.
再敲一次,再遍历一小部分时间就是可控的~~化整为零 】
ConcurrentHashMap(线程安全的 哈希表)
这个哈希表在扩容的时候,也是按照化整为零的方式进行的!!
Java 标准库直接提供了一些线程安全的 集合类
(Java 中也有"容器"这样的术语,指的是别的了)
2.9 HLEN
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
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
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
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"
3.命令小节
命令 | 执⾏效果 | 时间复杂度 |
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) |
hincrbyfloat key field n | 对应 field-value +n | O(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流模式通信的基本概念和一个简单的示例。 基本概念 面向连接࿱…...

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

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࿰…...

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

【调试笔记-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) 为 优质数对&#…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...

React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...
在 Spring Boot 项目里,MYSQL中json类型字段使用
前言: 因为程序特殊需求导致,需要mysql数据库存储json类型数据,因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...

水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关
在水泥厂的生产流程中,工业自动化网关起着至关重要的作用,尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关,为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多,其中不少设备采用Devicenet协议。Devicen…...