[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命令,该命令采⽤渐进式遍历哈希类型

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.哈希类型

  • 优点:简单、直观、灵活,尤其是针对信息的局部变更或者获取操作
  • 缺点:需要控制哈希在ziplisthashtable两种内部编码的转换,可能会造成内存的较⼤消耗

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

帧率和丢帧分析理论

一、丢帧问题概述 应用丢帧通常指的是在应用程序的界面绘制过程中&#xff0c;由于某些原因导致界面绘制的帧率下降&#xff0c;从而造成界面卡顿、动画不流畅等问题。以60Hz刷新率为例子&#xff0c;想要达到每秒60帧&#xff08;即60fps&#xff09;的流畅体验&#xff0c;每…

鹏哥C语言复习——函数栈帧的创建和销毁

目录 演示用代码&#xff1a; 提示&#xff1a;后文讲解时后缀为h的指的是16进制表示 疑惑1&#xff1a;自定义函数、库函数都是在main函数内部调用&#xff0c;那么是什么调用了main函数呢&#xff1f; 疑惑2&#xff1a;如何观察ebp、esp等寄存器的运行&#xff1f; 疑惑…

提升效率的AI工具集 - 轻松实现自动化

在这个快节奏、高效率的社会中&#xff0c;我们每个人都渴望能够找到提升工作效率的捷径。幸运的是&#xff0c;随着人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;越来越多的AI工具涌现出来&#xff0c;为我们提供了强大的支持。这些工具不仅能够帮助我们提高…

算法-分治和逆序

分治法&#xff08;Divide and Conquer&#xff09;是一种重要的算法设计范式&#xff0c;它通过将复杂的问题分解成更小、更易于管理和解决的子问题&#xff0c;然后递归地解决这些子问题&#xff0c;最后将子问题的解合并以得到原问题的解。分治法通常用于排序、搜索、数学计…

基于STM32F103C8T6单片机的DDS信号源设计

本设计能够输出三角波信号、方波信号和正弦波信号,主要由STM32F103C8T6最小核心板、电源供电电路模块、AD9833电路模块、矩阵按键电路模块、LCD1602液晶显示模块等组成。在设计中&#xff0c;使用STM32F103C8T6作为控制芯片&#xff0c;结合LCD1602液晶显示器&#xff0c;矩阵键…

稳了,搭建Docker国内源图文教程

大家好&#xff0c;之前分享了我的开源作品 Cloudflare Workers Proxy&#xff0c;它的作用是代理被屏蔽的地址&#xff0c;理论上支持代理任何被屏蔽的域名&#xff0c;使用方式也很简单&#xff0c;只需要设置环境变量 PROXY_HOSTNAME 为被屏蔽的域名&#xff0c;最后通过你的…

Unity多语言插件I2 Localization国际化应用

【就不收费了&#xff0c;要个关注不过分吧】 【图片来自插件官网&#xff0c;侵删】 前言 目前游戏往往都不会仅局限于国内语言&#xff0c;为了适应产品都要做国际化适配&#xff0c;因此会用到这个插件&#xff0c;这个插件要付费&#xff0c;因此请前往unity官网进行下载…

秒懂Linux之消息队列与信号量(了解)

目录 前言 消息队列原理 信号量理论 信号量原理 IPC资源 前言 消息队列与信息量目前已经不常用了&#xff0c;大家也可以参考共享内存去了解基本原理即可。 消息队列原理 消息队列提供了一个从一个进程向另外一个进程发送一块数据的方法 每个数据块都被认为是有一个类型&…

mfc140u.dll引发的软件故障怎么破?mfc140u.dll文件损坏的解决办法全知道!

当这个重要的 DLL 文件丢失或损坏时&#xff0c;用户可能会收到一个错误消息&#xff0c;提示 “程序无法启动&#xff0c;因为计算机中缺失 mfc140u.dll” 或类似的提示。这种情况不仅令人困扰&#xff0c;而且可以干扰正常的工作流程&#xff0c;尤其是当您依赖特定软件完成日…

KMP算法的实现

这是C算法基础-数据结构专栏的第二十六篇文章&#xff0c;专栏详情请见此处。 引入 KMP算法是一种可以快速查找某一字符串在一个文本中的所有出现的算法。 下面我们就来讲KMP算法的实现。 定义 Knuth–Morris–Pratt 算法&#xff0c;简称KMP算法&#xff0c;是由Knuth、Pratt…

基于VUE的教师教学质量网络评测评价统计分析系统

1、 选题的背景与意义 21世纪是信息化的世纪&#xff0c;我们的一些生活习惯因为计算机而发生改变&#xff0c;我们也逐渐习惯于通过计算机的各项功能来获得便利。这其中所带来的挑战和机遇为各行业的发展指明了一个方向。教学质量评测是一项琐碎而又十分细致的工作&#xf…

【永磁同步电机(PMSM)】 3. 基于Matlab 的仿真与控制

【永磁同步电机&#xff08;PMSM&#xff09;】 3. 基于Matlab 的仿真与控制 1. 电机的仿真与控制2. BLDC 电机与 PMSM 电机3. BLDC 的方波控制4. 磁场定向控制&#xff08;FOC&#xff09;5. 空间矢量调制 (SVM)6. PMSM 模型的频率响应估计 电机仿真和控制是能源生产、汽车、航…

Java对象一口气讲完!φ(* ̄0 ̄)

Java Object类 Java面向对象设计 - Java Object类 Java在java.lang包中有一个Object类。 所有Java类都直接或间接扩展Object类。 所有Java类都是Object类的子类Object类是所有类的超类。 Object类本身没有超类。 Object类的引用变量可以保存任何类的对象的引用。 以下代…

OSPFv3协议几类LSA介绍

OSPFv3协议介绍 与OSPFv2相比&#xff0c;OSPFv3在工作机制上与OSPFv2基本相同&#xff1b;但为了支持IPv6地址格式&#xff0c;OSPFv3对OSPFv2做了一些改动。OSPFv3基于OSPFv2基本原理增强&#xff0c;是一个独立的路由协议&#xff08;v3不兼容v2&#xff09;协议号仍然是89…

竹云赋能“中国·贵州”全省统一移动应用平台建设,打造政务服务“新引擎”

近日&#xff0c;2024中国国际大数据产业博览会在贵州贵阳圆满落幕。会上&#xff0c;由贵州省政府办公厅牵头建设的“中国贵州”全省统一移动应用平台正式发布&#xff0c;聚焦民生办事、政务公开、政民互动、扁平高效、数据赋能五大模块&#xff0c;旨在打造公平普惠的服务平…

Hbase操作手册

一&#xff1a;Hbase 创建数据库表 1.进入hbase shell 2.创建数据库表的命令&#xff1a;create 表名, 列族名1,列族名2,列族名N 3.如果想查看所有数据库表&#xff0c;可以使用list 命令&#xff1a; 4.可以看到&#xff0c;刚创建的数据库表user 已经在数据库表的列表中&…

单元格左边放文字右边放按钮

1 . 代码 /* 添加到你的CSS文件中 */ .switch-td { display: flex; justify-content: space-between; /* 两端对齐&#xff0c;这样文本和开关会分别靠左和靠右 */ align-items: left; /* 垂直居中 */ } /* 如果你不想改变其他<td>的默认左对齐&#xff0c;…

TTF与图片之间的相互转换,使用python,potrace,fontforge

概述 TTF是字体文件格式&#xff0c;里面存储的是矢量化的字体信息。TTF与图片之间的相互转换简单描述如下&#xff1a; 使用python中的PIL&#xff08;pillow&#xff09;图像库可以实现TTF转图片使用potrace可以将图片转为矢量文件svg&#xff0c;再进一步使用fontforge可以…

一天认识一个硬件之连接线

我们在日常工作生活中经常会用到许多连接线&#xff0c;比如视频线&#xff0c;USB线&#xff0c;但是他们的区别在哪里&#xff0c;可能太不清楚&#xff0c;今天就来给大家分享一下。 HDMI线 特点&#xff1a;HDMI线是一种全数字化视频和声音发送接口&#xff0c;可以发送未…

phpword读取word docx文档文本及图片转html格式

最近在做一个PHP读取word文档功能&#xff0c;搜索一圈后决定选择用phpword第三方组件。 composer安装phpWord composer require phpoffice/phpword如果你的文件是doc格式&#xff0c;直接另存为一个docx就行了&#xff1b;如果你的doc文档较多&#xff0c;可以下一个批量转…