【redis】Redis数据类型(二)Hash类型

目录

  • Hash类型介绍
    • 特性
    • hash 的内部编码方式/底层结构
      • hashtable
      • ziplist
      • listpack
    • 适用场景
      • 举例
    • 常用命令
      • hset
        • 示例
      • hsetnx
        • 示例:
      • hmset
        • 示例
      • hget
        • 示例
      • hmget
        • 示例
      • hgetall
        • 示例
      • hdel
        • 示例
      • hlen
        • 示例
      • hexists
        • 示例
      • hincrby
        • 示例
      • hincrbyfloat
        • 示例
      • hkeys
        • 示例
      • hvals
        • 示例

Hash类型介绍

Hash 类型是一种键值对集合,这种数据类型适合用于存储对象

特性

  • 键值对集合:Hash 类型可以存储多个键值对,每个键都有一个对应的值。
  • 二进制安全:Hash 类型的键和值都是二进制安全的,这意味着它们可以包含任何数据,包括二进制数据。
  • 大容量:单个 Hash 类型可以存储超过 4 亿个键值对。
  • 高效的查找速度:无论 Hash 中存储了多少数据,查找某个键的速度都非常快。

hash 的内部编码方式/底层结构

Redis 的 Hash 类型会根据实际情况在压缩列表(ziplist)和散列表(hashtable)之间进行切换,这主要取决于两个配置参数:hash-max-ziplist-entries 和 hash-max-ziplist-value。

  • hash-max-ziplist-entries:这个参数用于设置压缩列表可以存储的最大节点数量。如果一个 Hash 类型的元素数量超过这个值,那么就会从压缩列表切换到散列表。默认值为 512;
  • hash-max-ziplist-value:这个参数用于设置压缩列表中每个节点的最大值大小(以字节为单位)。如果一个 Hash 类型的任何元素的大小超过这个值,那么就会从压缩列表切换到散列表。默认值为 64。

hashtable

  • 最基本的哈希表(不是 java 标准库中的 HashTable),redis 内部对哈希表的实现方式和 java 中的哈希表可能不太一样,但是整体思想都是一样的;时间上复杂度O(1),但是空间上会有一定的浪费(hash 是一个数组,数组上有些位置有元素,有些位置没有元素).
  • 当 Hash 类型存储的字段和值的数量较多,或者字段和值的字符串长度较长时,Redis 会选择使用散列表作为底层实现。散列表是一种常见的键值对映射结构,它通过一个散列函数将键映射到一个桶中,然后在桶中进行查找。这种方式的优点是查找和修改数据的性能较高,但是占用的内存也较多。
  • Redis 的散列表(hash table)是一种常见的键值对映射结构,它通过一个散列函数将键映射到一个桶中,然后在桶中进行查找。Redis 的散列表使用链表法解决哈希冲突,即当多个键映射到同一个桶时,将它们存储在同一个链表中

ziplist

压缩列表,当哈希表里的元素比较少的时候,就优化成了 ziplist 了,在Redis7.0之前使用,特点是内存占用教少,能够节省空间,但是读写元素的速度比较慢;

  • 如果 hash 中的元素比较少,使用 ziplist 表示. 元素比较多的时候使用 hashtable 表示.
  • 每个 value 值的长度都比较短的,使用 ziplist 表示. 如果某个 value 长度太长,也会转化成 hashtable.
  • 压缩的本质就是对数据进行重新编码,不同的数据有不同的特点,结合这些特点,重新编码后,就能够缩小体积
  • 例如 abbcccdddd 重新编码就变成了 1a2b3c4d.

listpack

紧凑列表,在Redis7.0版本之后取代了ziplist,同样也是hash到达一定阀值后转换为hashtable。

适用场景

  1. 存储对象:Hash 类型可以存储多个键值对,非常适合用于存储对象。例如,你可以使用 Hash 类型存储用户的信息,如用户名、密码、邮箱等;
  2. 数据分析:你可以使用 Hash 类型存储各种统计数据,例如用户的行为数据,然后进行数据分析;
  3. 社交网络:在社交网络应用中,你可以使用 Hash 类型存储用户的朋友列表、粉丝列表等
  4. 购物车场景的使用。使用用户ID作为key,商品ID作为field,商品数量或规格等信息作为value,便于快速增删改查购物车中的商品项
  5. 缓存配置信息:应用程序的配置信息,如各种设置参数,可以集中存储在Hash中,方便统一管理和实时更新
  6. 权限列表管理: 用Hash存储用户的权限信息,key为用户ID,field表示权限标识符,value为权限状态(如允许/禁止)。
  7. 进度存储:如小说阅读进度、视频播放进度等场景,key可以是用户ID+资源ID组合,field为资源唯一标识,value为对应的进度值。
  8. 关系模型数据建模:当需要在Redis中模拟关系型数据库中的一对多或者多对多关系时,Hash可以作为一个轻量级的解决方案,简化数据结构设计
  9. 计数器集合:当需要统计一组相关联的数据项的不同维度计数时,可以使用Hash存储每个维度的计数值。

举例

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

常用命令

命令描述
hset key field valuefiled的不存在新增并返回1,如果filed已经存在就覆盖更新并返回0
hsetnx key field value如果filed不存在则设置值为字符串value并返回1,否则不做任何操作返回0
hgetall key field获取这个key的所有field-value,返回结果为数组
hdel key field删除field的value,删除成功返回1,删除失败返回0
hdel key删除key的所有field-value,删除成功返回1,删除失败返回0
hmset k1 f1 v1 k2 f2 v2 …批量操作一次性新增或更新多个field
hmget f1 f2 …批量操作一次性获取多个field的value
hexists key field判断field是否存在,存在返回1,否侧返回0
hsetnx key field valuefield不存在则设置值,否则不操作
hvals key获取hash结构的所有值

hset

  • 语法:hset key field value
  • 解释:
    • 将哈希表 key 中的域 field 的值设为 value 。
    • 如果 key 不存在,一个新的哈希表被创建并进行 HSET 操作。
    • 如果域 field 已经存在于哈希表中,旧值将被覆盖
  • 时间复杂度:O(1)
  • 返回值:
    • 如果 field 是哈希表中的一个新建域,并且值设置成功,返回 1 。
    • 如果哈希表中域 field 已经存在且旧值已被新值覆盖,返回 0 。
示例
127.0.0.1:6379[3]> hset mywebsite csdn "zhoujl.blog.csdn.net"
(integer) 1
127.0.0.1:6379[3]> hset mywebsite csdn "https://zhoujl.blog.csdn.net"
(integer) 0
127.0.0.1:6379[3]>

hsetnx

  • 语法:hsetnx key field value
  • 解释:
    • 将哈希表 key 中的域 field 的值设置为 value ,当且仅当域 field 不存在。
    • 若域 field 已经存在,该操作无效。
    • 如果 key 不存在,一个新哈希表被创建并执行 HSETNX 命令。
  • 时间复杂度:O(1)
  • 返回值:
    • 设置成功,返回 1 。
    • 如果给定域已经存在且没有操作被执行,返回 0 。
示例:
127.0.0.1:6379[3]> hsetnx user username admin
(integer) 1
127.0.0.1:6379[3]> hsetnx user userage 20
(integer) 1
127.0.0.1:6379[3]> hsetnx user username root
(integer) 0
127.0.0.1:6379[3]>

hmset

  • 语法:hmset key field value [field value …]
  • 解释:
    • 同时将多个 field-value (域-值)对设置到哈希表 key 中。
    • 此命令会覆盖哈希表中已存在的域。
    • 如果 key 不存在,一个空哈希表被创建并执行 HMSET 操作。
  • 复杂度:O(N), N 为 field-value 对的数量。
  • 返回值类型:
    • 如果命令执行成功,返回 OK 。
    • 当 key 不是哈希表(hash)类型时,返回一个错误。
示例
127.0.0.1:6379[3]> hmset role roleId 1 roleName admin
OK
127.0.0.1:6379[3]> hget role roleId
"1"
127.0.0.1:6379[3]> hget role roleName
"admin"
127.0.0.1:6379[3]>

hget

  • 语法:hget key field
  • 解释:返回哈希表 key 中给定域 field 的值
  • 时间复杂度:O(1)
  • 返回值:
    • 给定域的值。
    • 当给定域不存在或是给定 key 不存在时,返回 nil 。
示例
127.0.0.1:6379[3]> hset site redis redis.com
(integer) 1
127.0.0.1:6379[3]> hget site redis
"redis.com"
127.0.0.1:6379[3]> hget site mysql
(nil)
127.0.0.1:6379[3]>

hmget

  • 语法:hmget key field [field …]
  • 解释:
    • 返回哈希表 key 中,一个或多个给定域的值。
    • 如果给定的域不存在于哈希表,那么返回一个 nil 值。
    • 因为不存在的 key 被当作一个空哈希表来处理,所以对一个不存在的 key 进行 HMGET 操作将返回一个只带有 nil 值的表。
  • 时间复杂度:O(N), N 为给定域的数量。
  • 返回值:一个包含多个给定域的关联值的表,表值的排列顺序和给定域参数的请求顺序一样
示例
127.0.0.1:6379[3]> hmset pet dog anpei cat mimi
OK
127.0.0.1:6379[3]> hmget pet dog cat penguin
1) "anpei"
2) "mimi"
3) (nil)
127.0.0.1:6379[3]>

hgetall

  • 语法:hgetall key
  • 解释
    • 返回哈希表 key 中,所有的域和值。
    • 在返回值里,紧跟每个域名(field name)之后是域的值(value),所以返回值的长度是哈希表大小的两倍。
  • 时间复杂度:O(N), N 为哈希表的大小。
  • 返回值:
    • 以列表形式返回哈希表的域和域的值。
    • 若 key 不存在,返回空列表。
示例
127.0.0.1:6379[3]> hset city zz zhengzhou
(integer) 1
127.0.0.1:6379[3]> hset city hz hangzhou
(integer) 1
127.0.0.1:6379[3]> hgetall city
1) "zz"	# 属性/域
2) "zhengzhou" 	# 值
3) "hz"
4) "hangzhou"
127.0.0.1:6379[3]>

hdel

  • 语法:hdel key field [field …]
  • 解释:
    • 删除哈希表 key 中的一个或多个指定域,不存在的域将被忽略。
    • 注:在 Redis2.4 以下的版本里, HDEL 每次只能删除单个域,如果你需要在一个原子时间内删除多个域,请将命令包含在 MULTI / EXEC 块内。
  • 时间复杂度:O(N), N 为要删除的域的数量。
  • 返回值:被成功移除的域的数量,不包括被忽略的域。
示例
127.0.0.1:6379[3]> hgetall city
 1) "zz"
 2) "zhengzhou"
 3) "hz"
 4) "hangzhou"
 5) "kf"
 6) "kaifeng"
 7) "ly"
 8) "luoyang"
 9) "bj"
10) "beijing"
11) "sh"
12) "shanghai"
127.0.0.1:6379[3]> hdel city sh
(integer) 1
127.0.0.1:6379[3]> hdel city hz bj
(integer) 2
127.0.0.1:6379[3]> hgetall city
1) "zz"
2) "zhengzhou"
3) "kf"
4) "kaifeng"
5) "ly"
6) "luoyang"
127.0.0.1:6379[3]>

hlen

  • 语法:hlen key
  • 解释:返回哈希表 key 中域的数量。
  • 时间复杂度:O(1)
  • 返回值:
    • 哈希表中域的数量。
    • 当 key 不存在时,返回 0 。
示例
127.0.0.1:6379[3]> hgetall city
1) "zz"
2) "zhengzhou"
3) "kf"
4) "kaifeng"
5) "ly"
6) "luoyang"
127.0.0.1:6379[3]> hlen city
(integer) 3
127.0.0.1:6379[3]>

hexists

  • 语法:hexists key field
  • 解释:查看哈希表 key 中,给定域 field 是否存在。
  • 时间复杂度:O(1)
  • 返回值:
    • 如果哈希表含有给定域,返回 1 。
    • 如果哈希表不含有给定域,或 key 不存在,返回 0 。
示例
127.0.0.1:6379[3]> hexists city sh
(integer) 0
127.0.0.1:6379[3]> hexists city zz
(integer) 1
127.0.0.1:6379[3]>

hincrby

  • 语法:hincrby key field increment
  • 解释:
    • 为哈希表 key 中的域 field 的值加上增量 increment 。
    • 增量也可以为负数,相当于对给定域进行减法操作。
    • 如果 key 不存在,一个新的哈希表被创建并执行 HINCRBY 命令。
    • 如果域 field 不存在,那么在执行命令前,域的值被初始化为 0 。
    • 对一个储存字符串值的域 field 执行 HINCRBY 命令将造成一个错误。
    • 本操作的值被限制在 64 位(bit)有符号数字表示之内
  • 时间复杂度:O(1)
  • 返回值:执行 HINCRBY 命令之后,哈希表 key 中域 field 的值。
示例
# increment 为正数
127.0.0.1:6379[3]> HEXISTS counter page_view # 对空域进行设置
(integer) 0
127.0.0.1:6379[3]> HINCRBY counter page_view 200
(integer) 200
127.0.0.1:6379[3]> HGET counter page_view
"200"
# increment 为负数
127.0.0.1:6379[3]> HGET counter page_view
"200"
127.0.0.1:6379[3]> HINCRBY counter page_view -50
(integer) 150
127.0.0.1:6379[3]> HGET counter page_view
"150"
# 尝试对字符串值的域执行 HINCRBY 命令
127.0.0.1:6379[3]> HSET myhash string hello,world # 设定一个字符串值
(integer) 1
127.0.0.1:6379[3]> HGET myhash string
"hello,world"
127.0.0.1:6379[3]> HINCRBY myhash string 1 # 命令执行失败,错误。
(error) ERR hash value is not an integer
127.0.0.1:6379[3]> HGET myhash string # 原值不变
"hello,world"

hincrbyfloat

  • 语法:hincrbyfloat key field increment
  • 解释:
    • 为哈希表 key 中的域 field 加上浮点数增量 increment 。
    • 如果哈希表中没有域 field ,那么 HINCRBYFLOAT 会先将域 field 的值设为 0 ,然后再执行加法操作。
    • 如果键 key 不存在,那么 HINCRBYFLOAT 会先创建一个哈希表,再创建域 field ,最后再执行加法操作。
    • 当以下任意一个条件发生时,返回一个错误:
      • 域 field 的值不是字符串类型(因为 redis 中的数字和浮点数都以字符串的形式保存,所以它们都属于字符串类型)
      • 域 field 当前的值或给定的增量 increment 不能解释(parse)为双精度浮点数(double precision floating point number)
    • HINCRBYFLOAT 命令的详细功能和 INCRBYFLOAT 命令类似,请查看 INCRBYFLOAT 命令获取更多相关信息。
  • 时间复杂度:O(1)
  • 返回值:执行加法操作之后 field 域的值。
示例
# 值和增量都是普通小数
127.0.0.1:6379[3]> HSET mykey field 10.50
(integer) 1
127.0.0.1:6379[3]> HINCRBYFLOAT mykey field 0.1
"10.6"
# 值和增量都是指数符号
127.0.0.1:6379[3]> HSET mykey field 5.0e3
(integer) 0
127.0.0.1:6379[3]> HINCRBYFLOAT mykey field 2.0e2
"5200"
# 对不存在的键执行 HINCRBYFLOAT
127.0.0.1:6379[3]> EXISTS price
(integer) 0
127.0.0.1:6379[3]> HINCRBYFLOAT price milk 3.5
"3.5"
127.0.0.1:6379[3]> HGETALL price
1) "milk"
2) "3.5"
# 对不存在的域进行 HINCRBYFLOAT
127.0.0.1:6379[3]> HGETALL price
1) "milk"
2) "3.5"
127.0.0.1:6379[3]> HINCRBYFLOAT price coffee 4.5 # 新增 coffee 域
"4.5"
127.0.0.1:6379[3]> HGETALL price
1) "milk"
2) "3.5"
3) "coffee"
4) "4.5

hkeys

  • 语法:hkeys key
  • 解释:返回哈希表 key 中的所有域。
  • 时间复杂度:O(N), N 为哈希表的大小。
  • 返回值:
    • 一个包含哈希表中所有域的表。
    • 当 key 不存在时,返回一个空表。
示例
# 哈希表非空
127.0.0.1:6379[3]> HMSET website google www.google.com yahoo www.yahoo.com
OK
127.0.0.1:6379[3]> HKEYS website
1) "google"
2) "yahoo"
# 空哈希表/key 不存在
127.0.0.1:6379[3]> EXISTS fake_key
(integer) 0
127.0.0.1:6379[3]> HKEYS fake_key
(empty list or set)

hvals

  • 语法:hvals key
  • 解释:返回哈希表 key 中所有域的值。
  • 时间复杂度:O(N), N 为哈希表的大小。
  • 返回值:
    • 一个包含哈希表中所有值的表。
    • 当 key 不存在时,返回一个空表。
示例
# 非空哈希表
127.0.0.1:6379[3]> HMSET website google www.google.com yahoo www.yahoo.com
OK
127.0.0.1:6379[3]> HVALS website
1) "www.google.com"
2) "www.yahoo.com"
# 空哈希表/不存在的 key
127.0.0.1:6379[3]> EXISTS not_exists
(integer) 0
127.0.0.1:6379[3]> HVALS not_exists
(empty list or set)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

VS2019编译OSG3.7.0+OSGEarth3.3+OSGQt5.15.2时遇到的问题及解决方法

注:本次编译以文章《VS2019编译OSG3.7.0+OSGEarth3.3+OSGQt》为基础搜集资料并进行编译 一 OSG编译 1.Osg3.7.0编译中,cmake阶段按照文章步骤即可。 2.另外,还需要对以下三项进行设置,参照《OSG-OpenSceneGraph在WIN10与VS2022下的部署(OSG3.6.5+VS2022+Win10_x64)个…

RustGUI学习(iced)之小部件(二):如何使用滑动条部件

前言 本专栏是学习Rust的GUI库iced的合集,将介绍iced涉及的各个小部件分别介绍,最后会汇总为一个总的程序。 iced是RustGUI中比较强大的一个,目前处于发展中(即版本可能会改变),本专栏基于版本0.12.1. 概述…

mybatis基本使用

文章目录 1. mybatis2. 基本使用(1) maven坐标(2) 配置文件编写(3) 数据库操作(4) 注解查询 2. 基本配置(1) 读取外部配置文件(2) mapper映射 3. 映射文件查询删除/修改/新增 动态sql 1. mybatis MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高…

CSS盒子模型(如果想知道CSS有关盒子模型的知识点,那么只看这一篇就足够了!)

前言:在网页制作的时候,我们需要将网页中的元素放在指定的位置,那么我们如何将元素放到指定的位置上呢?这时候我们就需要了解盒子模型。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-CSD…

sCrypt全新上线RUNES功能

sCrypt智能合约平台全新上线一键etch/mint RUNES功能! 请访问 https://runes.scrypt.io/ 或点击阅读原文体验! 关于sCrypt sCrypt是BSV区块链上的一种智能合约高级语言。比特币使用基于堆栈的Script语言来支持智能合约,但是用原生Script编…

网络靶场实战-物联网安全Unicorn框架初探

背景 Unicorn 是一款基于 QEMU 的快速 CPU 模拟器框架,可以模拟多种体系结构的指令集,包括 ARM、MIPS、PowerPC、SPARC 和 x86 等。Unicorn使我们可以更好地关注 CPU 操作, 忽略机器设备的差异。它能够在虚拟内存中加载和运行二进制代码,并提…

密码加密案例

文章目录 描述思路错误关于增强for循环改变不了数组的值这一现象的疑问代码反思 描述 思路错误 应该是将其放入数组,而不是单纯的读到,因为你要对每一位数字进行操作 关于增强for循环改变不了数组的值这一现象的疑问 我们尝试使用增强for循环 键盘输…

uniapp使用地图开发app

使用uniapp开发app中使用到地图的坑: 1、简单使用地图的功能比较简单,仅使用到地图选点和定位功能:(其中问题集中在uni.chooseLocation中)下面是api官网地址 uni.getLocation(OBJECT) | uni-app官网 官方建议app端使…

迁移学习基础知识

简介 使用迁移学习的优势: 1、能够快速的训练出一个理想的结果 2、当数据集较小时也能训练出理想的效果。 注意:在使用别人预训练的参数模型时,要注意别人的预处理方式。 原理: 对于浅层的网络结构,他们学习到的…

视频批量剪辑新纪元:轻松调整音频采样率,一键实现高效视频处理!

视频剪辑已成为我们日常生活和工作中不可或缺的一部分。然而,面对大量的视频文件,如何高效地进行批量剪辑,同时又能轻松调整音频采样率,成为了许多视频制作人员、自媒体从业者、教育者和学生的共同需求。 第一步,进入…

[C++基础学习]----02-C++运算符详解

前言 C中的运算符用于执行各种数学或逻辑运算。下面是一些常见的C运算符及其详细说明:下面详细解释一些常见的C运算符类型,包括其原理和使用方法。 正文 01-运算符简介 算术运算符: a、加法运算符():对两个…

4.27日学习打卡----初学Redis(四)

4.27日学习打卡 目录: 4.27日学习打卡一. Redis的配置文件二. Redis构建Web应用实践环境搭建redis的优点引入本地缓存Google 开源工具GuavaGuava实现本地缓存 一. Redis的配置文件 在Redis的解压目录下有个很重要的配置文件 redis.conf ,关于Redis的很多…

达梦(DM) SQL日期操作及分析函数

达梦DM SQL日期操作及分析函数 日期操作SYSDATEEXTRACT判断一年是否为闰年周的计算确定某月内第一个和最后一个周末某天的日期确定指定年份季度的开始日期和结束日期补充范围内丢失的值按照给定的时间单位查找使用日期的特殊部分比较记录 范围处理分析函数定位连续值的范围查找…

如何通过安全数据传输平台,保护核心数据的安全传输?

在数字化的浪潮中,企业的数据安全传输显得尤为关键。随着网络攻击手段的日益复杂,传统的数据传输方式已不再安全,这就需要我们重视并采取有效的措施,通过安全数据传输平台来保护核心数据。 传统的数据传输面临的主要问题包括&…

Bun 入门到精通(一)

Bun 是什么? Bun 是用于 JavaScript 和 TypeScript 应用程序的多合一工具包。它作为一个名为 bun 的可执行文件提供。 其核心是 Bun 运行时,这是一个快速的 JavaScript 运行时,旨在替代 Node.js。它是用 Zig 编写的,并由 JavaSc…

数字文旅重塑旅游发展新格局:以数字化转型为突破口,提升旅游服务的智能化水平,为游客带来全新的旅游体验

随着信息技术的迅猛发展,数字化已成为推动各行各业创新发展的重要力量。在旅游业领域,数字文旅的兴起正以其强大的驱动力,重塑旅游发展的新格局。数字文旅以数字化转型为突破口,通过提升旅游服务的智能化水平,为游客带…

C#基础|OOP、类与对象的认识

哈喽,你好,我是雷工! 所有的面向对象的编程语言,都是把我们要处理的“数据”和“行为”封装到类中。 以下为OOP的学习笔记。 01 什么是面向对象编程(OOP)? 设计类:就是根据需求设计…

论文精读InstructPix2Pix: Learning to Follow Image Editing Instructions

InstructPix2Pix: Learning to Follow Image Editing Instructions 我们提出了一种根据人类指令编辑图像的方法:给定输入图像和告诉模型该做什么的书面指令,我们的模型遵循这些指令来编辑图像。 为了获得这个问题的训练数据,我们结合了两个大型预训练模…

输入输出重定向,追加重定向(Linux)

文章目录 一、输出重定向二、追加重定向三.输入重定向总结 一、输出重定向 我们在使用echo内容时,会把内容显示在显示器上。 echo自动换行。 我们如果输入 echo “hello linux” >file.txt 我们运行一下就会发现系统中多了一个file.txt的文件,如果这…

C语言 基本数据类型及大小

一、基本数据类型 1.整型int 整型的关键字是int,定义一个整型变量时,只需要用int来修饰即可。也分为短整型和长整型。 2.浮点型 浮点型又分单精度浮点型float和双精度浮点型double。 3.字符型char 前面的整型和浮点型都是用于存放数字。字符型&…