[Redis][Hash]详细讲解
目录
- 0.前言
- 1.常见命令
- 1.HSET
- 2.HGET
- 3.HEXISTS
- 4.HDEL
- 5.HKEYS
- 6.HVALS
- 7.HGETALL
- 8.HMGET
- 9.HLEN
- 10.HSETNX
- 11.HINCRBY
- 12.HINCRBYFLOAT
- 2.内部编码
- 1.ziplist(压缩链表)
- 2.hashtable(哈希表)
- 3.使用场景
- 4.缓存方式对比
- 1.原⽣字符串类型
- 2.序列化字符串类型
- 3.哈希类型
0.前言
-
在Redis中,哈希类型是指值本⾝是⼀个键值对结构,形如
key="key",value={{field1, value1}, ..., {fieldN, valueN}}
-
字符串和哈希类型对比:存储一个uid为1的用户对象,姓名James,年龄28
-
注意:哈希类型中的映射关系通常称为
field-value
,⽤于区分Redis整体的键值对(key-value
), 注意这⾥的value
是指field
对应的值,不是键(key
)对应的值
1.常见命令
1.HSET
- 功能:设置
hash
中指定的字段(field
)的值(value
) - 语法:`HSET key field value [field value]
- 返回值:添加字段的个数
- 时间复杂度:插入一组
field
为 O ( 1 ) O(1) O(1),插入N组field
为 O ( N ) O(N) O(N)
2.HGET
- 功能:获取hash中指定字段的值
- 语法:
HGET key field
- 返回值:字段对应的值或者
nil
- 时间复杂度: O ( 1 ) O(1) O(1)
3.HEXISTS
- 功能:判断hash中是否有指定的字段
- 语法:
HEXISTS key field
- 返回值:1表示存在,0表示不存在
4.HDEL
- 功能:删除hash中指定的字段
- 语法:
HDEL key field [field ...]
- 返回值:本次操作删除的字段个数
- 时间复杂度:删除一个元素为 O ( 1 ) O(1) O(1),删除N个元素为 O ( N ) O(N) O(N)
5.HKEYS
- 功能:获取hash中的所有字段
- 先根据key找到对应的hash -> O ( 1 ) O(1) O(1)
- 然后再遍历hash -> O ( N ) O(N) O(N)
- 语法:
HKEYS key
- 返回值:字段列表
- 时间复杂度: O ( N ) O(N) O(N),N为
field
的个数 - 注意:该操作也是存在一定风险的,类似于之前介绍的
KEYS
6.HVALS
- 功能:获取hash中所有的值
- 语法:
HVALS key
- 返回值:所有的值
- 时间复杂度: O ( N ) O(N) O(N),N为
field
的个数
7.HGETALL
- 功能:获取hash中的所有字段以及对应的值
- 语法:
HGETALL key
- 返回值:字段和对应的值
- 时间复杂度: O ( N ) O(N) O(N),N为
field
的个数 - 注意:在使⽤
HGETALL
时,如果哈希元素个数⽐较多,会存在阻塞Redis的可能- 如果只需要获取部分field,可以使⽤
HMGET
- 如果⼀定要获取全部
field
,可以尝试使⽤HSCAN
命令,该命令采⽤渐进式遍历哈希类型
- 如果只需要获取部分field,可以使⽤
8.HMGET
- 功能:一次获取hash中多个字段的值
- 语法:
HMGET key field [field ...]
- 返回值:字段对应的值或者
nil
- 时间复杂度:只查询⼀个元素为 O ( 1 ) O(1) O(1),查询多个元素为 O ( N ) O(N) O(N),N为查询元素个数
9.HLEN
- 功能:获取hash中的所有字段的个数
- 语法:
HLEN key
- 返回值:字段个数
- 时间复杂度: O ( 1 ) O(1) O(1)
10.HSETNX
- 功能:在字段不存在的情况下,设置hash中的字段和值
- 语法:
HSETNX key field value
- 返回值:1表示设置成功,0表示失败
- 时间复杂度: O ( 1 ) O(1) O(1)
11.HINCRBY
- 功能:将hash中字段对应的数值添加指定的值
- 语法:
HINCRBY key field increment
- 返回值:该字段变化之后的值
- 时间复杂度: O ( 1 ) O(1) O(1)
12.HINCRBYFLOAT
- 功能:
HINCRBY
的浮点数版本 - 语法:
HINCRBYFLOAT key field increment
- 返回值:该字段变化之后的值
- 时间复杂度: O ( 1 ) O(1) O(1)
2.内部编码
1.ziplist(压缩链表)
- 当哈希类型元素个数⼩于
hash-max-ziplist-entries
配置(默认512个)、 同时所有值都⼩于hash-max-ziplist-value
配置(默认64字节)时,Redis会使⽤ziplist
作为哈希的内部实现 ziplist
使⽤更加紧凑的结构实现多个元素的连续存储,所以在节省内存⽅⾯⽐hashtable
更加优秀
2.hashtable(哈希表)
- 当哈希类型⽆法满⾜
ziplist
的条件时,Redis会使⽤hashtable
作为哈希的内部实现,因为此时ziplist
的读写效率会下降,⽽hashtable
的读写时间复杂度为O(1) - 哈希类型的内部编码,以及响应的变化
- 当
field
个数⽐较少且没有⼤的value
时,内部编码为ziplist
- 当有
value
⼤于64字节时,内部编码会转换为hashtable
- 当
field
个数超过512时,内部编码也会转换为hashtable
- 当
3.使用场景
-
关系型数据表记录的两条用户信息
-
映射关系表⽰⽤⼾信息:可以将每个⽤⼾的
id
定义为键后缀,多对field-value
对应⽤⼾的各个属性
-
优势:相⽐于使⽤JSON格式的字符串缓存⽤⼾信息,哈希类型变得更加直观,并且在更新操作上变得更灵活
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){响应404return null;}// 将缓存以哈希类型保存Redis 执⾏命令: hmset key name userInfo.name age userInfo.age city userInfo.city// 写⼊缓存,为了防⽌数据腐烂(rot),设置过期时间为 1 ⼩时Redis 执⾏命令: expire key 3600// 返回用户信息return userInfo; }
-
需要注意的是哈希类型和关系型数据库有两点不同之处:
-
哈希类型是稀疏的,⽽关系型数据库是完全结构化的
- 例如:哈希类型每个键可以有不同的
field
,⽽关系型数据库⼀旦添加新的列,所有⾏都要为其设置值,即使为null
- 例如:哈希类型每个键可以有不同的
-
关系数据库可以做复杂的关系查询,⽽Redis去模拟关系型复杂查询
- 例如:联表查询、聚合查询等基本不可能,维护成本⾼
-
4.缓存方式对比
- 目前学习了三种方法缓存用户信息,以下给出三种方案的实现方法和优缺点分析
1.原⽣字符串类型
- 说明:使⽤字符串类型,每个属性⼀个键
- 优点:实现简单,针对个别属性变更也很灵活
- 缺点:占⽤过多的键,内存占⽤量较⼤,同时⽤⼾信息在Redis中⽐较分散,缺少内聚性,所以这种⽅案基本没有实⽤性
- 示例:
set user:1:name James set user:1:age 23 set user:1:city Beijing
2.序列化字符串类型
- 说明:例如JSON格式
- 优点:针对总是以整体作为操作的信息⽐较合适,编程也简单。同时,如果序列化⽅案选择合适,内存的使⽤效率很⾼
- 缺点:本⾝序列化和反序列需要⼀定开销,同时如果总是操作个别属性则⾮常不灵活
- 示例:
set user:1 经过序列化后的⽤⼾对象字符串
3.哈希类型
- 优点:简单、直观、灵活,尤其是针对信息的局部变更或者获取操作
- 缺点:需要控制哈希在
ziplist
和hashtable
两种内部编码的转换,可能会造成内存的较⼤消耗
相关文章:

[Redis][Hash]详细讲解
目录 0.前言1.常见命令1.HSET2.HGET3.HEXISTS4.HDEL5.HKEYS6.HVALS7.HGETALL8.HMGET9.HLEN10.HSETNX11.HINCRBY12.HINCRBYFLOAT 2.内部编码1.ziplist(压缩链表)2.hashtable(哈希表) 3.使用场景4.缓存方式对比1.原⽣字符串类型2.序列化字符串类型3.哈希类型 0.前言 在Redis中&am…...

上半年亏损扩大/百亿资产重组终止,路畅科技如何“脱困”?
在智能网联汽车市场形势一片大好的前提下,路畅科技上半年的营收却出现了下滑,并且亏损也进一步扩大。 2024年半年度报告显示,路畅科技营业收入1.35亿元,同比下滑7.83%;实现归属上市公司股东的净利润为亏损2491.99万元…...

协议IP规定,576字节和1500字节的区别
576字节和1500字节的区别主要在于它们是IP数据报在数据链路层中的最大传输单元(MTU)的不同限制。 576字节:这个数值通常与IP层(网络层)的数据报有关,它指的是在不进行分片的情况下,IP数据…...

对抗攻击的详细解析:原理、方法与挑战
对抗攻击的详细解析:原理、方法与挑战 对抗攻击(Adversarial Attack)是现代机器学习模型,尤其是深度学习模型中的一个关键安全问题。其本质在于,通过对输入数据添加精微的扰动,人类难以察觉这些扰动&#…...

Python办公自动化教程(003):PDF的加密
【1】代码 from PyPDF2 import PdfReader, PdfWriter# 读取PDF文件 pdf_reader PdfReader(./file/Python教程_1.pdf) pdf_writer PdfWriter()# 对第1页进行加密 page pdf_reader.pages[0]pdf_writer.add_page(page) # 设置密码 pdf_writer.encrypt(3535)with open(./file/P…...

python全栈学习记录(十七)logging、json与pickle、time与datatime、random
logging、json与pickle、time与datatime、random 文章目录 logging、json与pickle、time与datatime、random一、logging二.json与pickle三.time与datatime四.random 一、logging logging模块用来记录日志信息。 import logging # 进行基本的日志配置 logging.basicConfig( fi…...

【艾思科蓝】JavaScript在数据可视化领域的探索与实践
【ACM出版 | EI快检索 | 高录用】2024年智能医疗与可穿戴智能设备国际学术会议(SHWID 2024)_艾思科蓝_学术一站式服务平台 更多学术会议请看 学术会议-学术交流征稿-学术会议在线-艾思科蓝 目录 引言 JavaScript可视化库概览 D3.js基础入门 1. 引入…...

【标准库的典型内容】std::declval
一、 d e c l v a l declval declval的基本概念和常规范例 s t d : : d e c l v a l std::declval std::declval 是 C 11 C11 C11标准中出现的一个函数模板。这个函数模板设计的比较奇怪(没有实现,只有声明),因此无法被调用&…...

深入了解package.json文件
在前端项目开发中,我们经常会遇到package.json文件。这个文件不仅是一个简单的配置文件,它还承担了项目管理的重任。下面,我们将深入探讨package.json文件的各个字段和作用,并通过实例来帮助你更好地理解和使用它。 package.json…...

【基础知识】网络套接字编程
套接字 IP地址 port(端口号) socket(套接字) socket常见API //创建套接字 int socket(int domain, int type, int protocol); //绑定端口 int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); //监听套接字…...

小程序地图展示poi帖子点击可跳转
小程序地图展示poi帖子点击可跳转 是类似于小红书地图功能的需求 缺点 一个帖子只能有一个点击事件,不适合太复杂的功能,因为一个markers只有一个回调回调中只有markerId可以使用。 需求介绍 页面有地图入口,点开可打开地图界面地图上展…...

传统到AI 大数据分析的演变,颠覆智慧水电的未来?
传统到AI 大数据分析的演变,颠覆智慧水电的未来? 前言传统到AI 大数据分析的演变 前言 水电作为一种重要的能源形式,一直在我们的生活中扮演着至关重要的角色。而如今,随着科技的飞速发展,智慧水电和 AI 大数据应用的…...

while语句
1.while使用 打印1-10 #include<stdio.h> int main() {int a 1;while (10 > a){printf("%d\n", a);a 1;}return 0; } 2.while语句中的break,continue break: 跳出while语句 #include<stdio.h> int main() {int a 0;wh…...

机器学习(西瓜书)第 10 章 降维与度量学习
10.1 k近邻学习kNN k 近邻(k-Nearest Neighbor,简称kNN)学习是一种常用的监督学习方法,其工作机制非常简单:给定测试样本,基于某种距离度量找出训练集中与其最靠近的k个训练样本,然后基于这k个 “邻居”的信息来进行预测.通常,在…...

828华为云征文 | 云服务器Flexus X实例,Docker集成搭建Halo博客平台
828华为云征文 | 云服务器Flexus X实例,Docker集成搭建Halo博客平台 Halo博客平台是一款基于Java的开源博客系统,以其简单易用、功能强大、美观大方等特点而受到广泛欢迎,采用了多种先进的技术框架,包括Freemarker模板引擎、Vue.j…...

Android carrier_list.textpb 和apns-conf.xml 配置文件参考
简介 针对SIM 的APN配置是在apns-conf.xml,而Google源码中有apns-full-conf.xml案例参考,是加入了carrier_id的统一配置,就不用单独的一张张卡配了。 apns-conf.xml和apns-full-conf.xml有什么区别? 在于它们包含的配置内容和复杂性,full包含了carrier_id字段。 详细代…...

二期 1.4 Nacos安装部署 - Window版
本文目录 Nacos支持三种部署模式环境准备下载Nacos启动登录服务注册与查看Nacos支持三种部署模式 单机模式 - 用于测试和单机试用。集群模式 - 用于生产环境,确保高可用。多集群模式 - 用于多数据中心场景。以 Window单机模式 抛转引玉,其它部署方式参考官方文档: https://n…...

vue3基础九问,你会几问
1. Vue是什么? Vue.js 是一个用于构建用户界面的渐进式 JavaScript 框架。它的核心库只关注视图层,采用自下而上的增量开发设计,这使得你可以将 Vue 轻松地整合到现有的项目中,或者与其他前端库一起使用。Vue 的目标是通过提供反…...

Linux系统应用之知识补充——OpenEuler(欧拉)的安装和基础配置
前言 这篇文章将会对OpenEuler的安装进行详解,一步一步跟着走下去就可以成功 注意 :以下的指令操作最好在root权限下进行(即su - root) ☀️工贵其久,业贵其专! 1、OpenEuler的安装 这里我不过多介绍&a…...

Git(4):修改git提交日志
修改最新一次提交的信息 git commit --amend 修正提交信息 在打开的编辑器中修改信息,保存并退出,Git 会用新的提交信息替换掉旧的提交信息(commit-id 变化)。也可以使用 git commit --amend -m "" 直接修改日志&#…...

【深度学习】(1)--神经网络
文章目录 深度学习神经网络1. 感知器2. 多层感知器偏置 3. 神经网络的构造4. 模型训练损失函数 总结 深度学习 深度学习(DL, Deep Learning)是机器学习(ML, Machine Learning)领域中一个新的研究方向。 从上方的内容包含结果,我们可以知道,在学习深度学…...

测试文件和数据库文件
接口测试 flaks项目入口文件manage.py路由配置 import requests#首先面向对象作封装,避免相同代码反复编写 class HttpApiTest:def test_get(self,url,data{}): #用来测试get方法的接口 #self通过共享self类中间的变量 #url用来请求接口 #data可传可不传res reques…...

redis集群模式连接
目录 一:背景 二:实现过程 三:总结 一:背景 redis集群通过将数据分散存储在多个主节点上,每个主节点可以有多个从节点进行数据的复制,以此来实现数据的高可用性和负载均衡。在集群模式下,客户…...

Linux高级I/O:多路转接模型
目录 一.常见的IO模型介绍二.多路转接I/O1.select1.1.函数解析1.2. select特点和缺点1.3.基于 select 的多客户端网络服务器 2.poll2.1.poll函数解析2.2.poll特点和缺点2.3.基于poll的tcp服务器 3.epoll3.1.系列函数解析3.2.epoll原理解析2.3.基于 select 的多客户端网络服务器…...

MongoDB Limit 与 Skip 方法
MongoDB Limit 与 Skip 方法 MongoDB 是一个流行的 NoSQL 数据库,它提供了灵活的数据存储和强大的查询功能。在处理大量数据时,我们常常需要限制返回的结果数量或者跳过一部分结果,这时就可以使用 MongoDB 的 limit 和 skip 方法。 Limit 方…...

【2025】中医药健康管理小程序(安卓原生开发+用户+管理员)
博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…...

VulnHub-Bilu_b0x靶机笔记
Bilu_b0x 靶机 概述 Vulnhub 的一个靶机,包含了 sql 注入,文件包含,代码审计,内核提权。整体也是比较简单的内容,和大家一起学习 Billu_b0x.zip 靶机地址: https://pan.baidu.com/s/1VWazR7tpm2xJZIGUS…...

Python | Leetcode Python题解之第421题数组中两个数的最大异或值
题目: 题解: class Trie:def __init__(self):# 左子树指向表示 0 的子节点self.left None# 右子树指向表示 1 的子节点self.right Noneclass Solution:def findMaximumXOR(self, nums: List[int]) -> int:# 字典树的根节点root Trie()# 最高位的二…...

如何将普通Tokenizer变成Fast Tokenizer
现在的huggingface库里面Tokenizer有两种,一种就是普通的,另一种是fast的。fast和普通的区别就是fast使用rust语言编写,在处理大量文本的时候会更快。我自己测试的时候单一一句的话fast要比普通的慢一些,当量叠上来,到…...

联合复现!考虑最优弃能率的风光火储联合系统分层优化经济调度!
前言 目前,尽管不断地追逐可再生能源全额消纳方式,大幅减小弃风弃光电量,但是若考虑风电、光伏发电的随机属性,全额消纳可能造成电网峰谷差、调峰难度及调峰调频等辅助服务费用的剧增,引起电网潜在运行风险。因此&…...