Redis数据结构:Hash类型全面解析

这篇具有很好参考价值的文章主要介绍了Redis数据结构:Hash类型全面解析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Redis,作为一个开源的、内存中的数据结构存储系统,以其出色的性能和灵活的数据类型,广泛应用于缓存、消息队列、发布订阅系统等多种场景。在 Redis 的五种基本数据类型中,Hash 类型是一种非常重要的数据类型。它可以存储键值对的集合,且能够用小于1毫秒的时间复杂度进行添加、删除、更新和查找操作,因此在实际应用中有着广泛的用途。

在接下来的文章中,我将详细介绍 Redis 的 Hash 类型,包括它的内部实现、主要特性、常用命令以及应用场景。无论你是刚接触 Redis 的新手,还是已经有一定经验的开发者,我相信你都能从这篇文章中学到一些有用的知识。让我们一起深入了解 Redis 的 Hash 类型,探索它的魅力所在。



1、Redis-Hash数据类型
1.1、Redis-Hash类型简介

Redis 的 Hash 类型是一种键值对集合,这种数据类型适合用于存储对象。在 Hash 类型中,每个键都有一个对应的值,这和 Python 的字典、Java 的 HashMap 以及 JavaScript 的对象非常相似。

以下是 Redis Hash 类型的一些主要特性:

  1. 键值对集合:Hash 类型可以存储多个键值对,每个键都有一个对应的值。

  2. 二进制安全:Hash 类型的键和值都是二进制安全的,这意味着它们可以包含任何数据,包括二进制数据。

  3. 大容量:单个 Hash 类型可以存储超过 4 亿个键值对。

  4. 高效的查找速度:无论 Hash 中存储了多少数据,查找某个键的速度都非常快。

1.2、Redis-Hash应用场景

Redis 的 Hash 类型是一种键值对集合,适合用于存储对象,因此在很多场景下都有着广泛的应用。以下是一些常见的应用场景:

  1. 存储对象:Hash 类型可以存储多个键值对,非常适合用于存储对象。例如,你可以使用 Hash 类型存储用户的信息,如用户名、密码、邮箱等;

  2. 数据分析:你可以使用 Hash 类型存储各种统计数据,例如用户的行为数据,然后进行数据分析;

  3. 社交网络:在社交网络应用中,你可以使用 Hash 类型存储用户的朋友列表、粉丝列表等

以上只是一些常见的应用场景,实际上,由于 Redis 的灵活性,你可以根据自己的需求,将 Redis 的 Hash 类型应用在更多的场景中。


2、Redis-Hash底层结构
2.1、Redis-Hash底层结构介绍

Redis 的 Hash 类型的底层实现是一个非常优化的数据结构,它会根据实际情况选择使用紧凑的压缩列表(ziplist)或者散列表(hashtable)作为底层实现。

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

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

这两个参数都可以在 Redis 的配置文件中进行设置。通过调整这两个参数,你可以根据自己的应用特性,选择更倾向于节省内存,还是更倾向于提高性能。

  1. 从压缩列表转换到散列表:当 Hash 类型存储的字段和值的数量超过 hash-max-ziplist-entries 的值,或者任何字段或值的大小超过 hash-max-ziplist-value 的值时,Redis 会将底层结构从压缩列表转换为散列表。这个过程是自动进行的,对用户来说是透明的。
  2. 从散列表转换到压缩列表:然而,一旦 Hash 类型的底层结构被转换为散列表,就无法再转换回压缩列表。这是因为散列表的性能更高,而且在大多数情况下,一旦一个 Hash 类型的大小超过了一定的阈值,那么它的大小就很可能会继续增长。
2.2、Redis-压缩列表(ziplist)

当 Hash 类型存储的字段和值的数量较少,且字段和值的字符串长度较短时,Redis 会选择使用压缩列表作为底层实现。压缩列表是一种为节省内存而设计的特殊编码结构,它将所有的字段和值紧凑地存储在一起。这种方式的优点是占用内存少,但是在需要修改数据时,可能需要对整个压缩列表进行重写,性能较低。

Redis 的压缩列表(ziplist)是一种特殊的编码结构,它被设计用来节省内存。压缩列表将所有的元素紧凑地存储在一起,每个元素都只占用连续的内存空间。

一个压缩列表的结构如下:

+---------+---------+--------+---------+---------+---------+--------+
| zlbytes | zltail  | zllen  | entry_1 | entry_2 |  ...    | zlend  |
+---------+---------+--------+---------+---------+---------+--------+

Ps:在 Redis 的源代码中,压缩列表(ziplist)的结构并没有直接定义为一个 C 结构体,而是通过一系列的宏和函数来操作一段连续的内存。

属性 说明
“zlbytes” 一个 4 字节的整数,表示整个压缩列表占用的字节数量,包括 <zlbytes> 自身的大小。
“zltail” 一个 4 字节的整数,表示压缩列表中最后一个元素的偏移量。这个偏移量是相对于整个压缩列表的起始地址的。
“zllen” 一个 2 字节的整数,表示压缩列表中的元素数量。如果元素数量超过 65535,那么这个值就会被设定为 65535,需要遍历整个压缩列表才能获取到实际的元素数量。
“entry” 压缩列表中的元素,每个元素都由一个或多个字节组成。每个元素的第一个字节(又称为"entry header")用于表示这个元素的长度以及编码方式。
“zlend” 一个字节,值为 255,表示压缩列表的结束。
2.3、Redis-散列表(hashtable)

当 Hash 类型存储的字段和值的数量较多,或者字段和值的字符串长度较长时,Redis 会选择使用散列表作为底层实现。散列表是一种常见的键值对映射结构,它通过一个散列函数将键映射到一个桶中,然后在桶中进行查找。这种方式的优点是查找和修改数据的性能较高,但是占用的内存也较多。

Redis 的散列表(hash table)是一种常见的键值对映射结构,它通过一个散列函数将键映射到一个桶中,然后在桶中进行查找。Redis 的散列表使用链表法解决哈希冲突,即当多个键映射到同一个桶时,将它们存储在同一个链表中。

在 Redis 的源代码中,散列表的结构定义如下:

typedef struct dictEntry {
    void *key;
    void *val;
    struct dictEntry *next;
} dictEntry;

typedef struct dictht {
    dictEntry **table;
    unsigned long size;
    unsigned long sizemask;
    unsigned long used;
} dictht;

typedef struct dict {
    dictht ht[2];
    long rehashidx; /* rehashing not in progress if rehashidx == -1 */
    int iterators; /* number of iterators currently running */
} dict;

其中:

  • dictEntry 结构体表示散列表中的一个节点,包含键(key)、值(val)和指向下一个节点的指针(next)。

  • dictht 结构体表示一个散列表,包含指向哈希表数组的指针(table)、哈希表数组的大小(size)、哈希表数组大小掩码(sizemask)和已使用的节点数量(used)。

  • dict 结构体表示一个字典,包含两个散列表(ht)、当前进行 rehash 的索引(rehashidx)和当前运行的迭代器数量(iterators)。

这就是 Redis 散列表的结构。


3、Hash 常用命令

以下是 Redis 中与 Hash 类型相关的一些命令:

3.1、设置Hash值

Redis 中设置 Hash 值的命令是 HSET,它的语法如下:

HSET key field value

其中,key 是哈希表的名称,field 是哈希表中的字段名,value 是字段对应的值。如果哈希表中原本不存在该字段,则会创建一个新的字段,并将其值设置为指定的值。如果该字段已经存在,则会覆盖原有的值。

例如,我们可以使用以下命令设置一个名为 user:1001 的哈希表中的字段 name 的值为 Alice

HSET user:1001 name Alice

如果需要同时设置多个字段的值,可以使用 HMSET 命令,它的语法如下:

HMSET key field1 value1 [field2 value2 ...]

例如,我们可以使用以下命令同时设置 user:1001 哈希表中的 nameage 字段的值:

HMSET user:1001 name Alice age 25

这样就可以一次性设置多个字段的值了。

在 Redis 中,获取 Hash 值的命令是 HGET,它的语法如下:

HGET key field

其中,key 是哈希表的名称,field 是哈希表中的字段名。

例如,我们可以使用以下命令获取一个名为 user:1001 的哈希表中的字段 name 的值:

HGET user:1001 name
3.2、获取Hash值

如果需要获取哈希表中的多个字段的值,可以使用 HMGET 命令,它的语法如下:

HMGET key field1 [field2 ...]

例如,我们可以使用以下命令获取 user:1001 哈希表中的 nameage 字段的值:

HMGET user:1001 name age

如果需要获取哈希表中所有的字段和值,可以使用 HGETALL 命令,它的语法如下:

HGETALL key

例如,我们可以使用以下命令获取 user:1001 哈希表中的所有字段和值:

HGETALL user:1001
3.3、删除Hash值

在 Redis 中,删除 Hash 值的命令是 HDEL,它的语法如下:

HDEL key field [field ...]

其中,key 是哈希表的名称,field 是要删除的字段名。你可以一次删除一个或多个字段。

例如,我们可以使用以下命令删除一个名为 user:1001 的哈希表中的字段 name

HDEL user:1001 name

如果你想要删除多个字段,可以在命令后面依次列出这些字段的名字,例如:

HDEL user:1001 name age

这个命令会删除 user:1001 哈希表中的 nameage 字段。

需要注意的是,HDEL 命令只会删除指定的字段及其值,而不会删除整个哈希表。如果你想要删除整个哈希表,可以使用 DEL 命令,例如:

DEL user:1001

这个命令会删除整个 user:1001 哈希表。

3.4、其他Hash命令

Redis 中 Hash 其他的一些常用命令还有:文章来源地址https://www.toymoban.com/news/detail-691898.html

  1. HEXISTS key field:查看哈希表 key 中,指定的字段是否存在。
  2. HLEN key:获取哈希表中字段的数量。
  3. HKEYS key:获取所有哈希表中的字段。
  4. HVALS key:获取哈希表中所有值。
  5. HGETALL key:获取在哈希表中指定 key 的所有字段和值。
  6. HINCRBY key field increment:为哈希表 key 中的指定字段的整数值加上增量 increment 。
  7. HINCRBYFLOAT key field increment:为哈希表 key 中的指定字段的浮点数值加上增量 increment 。
  8. HMSET key field value [field value ...]:同时将多个 field-value (字段-值)对设置到哈希表的 key 中。
  9. HMGET key field [field ...]:获取所有给定字段的值。

到了这里,关于Redis数据结构:Hash类型全面解析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Redis Hash数据结构探秘

    在网上看了不少文章都是指导使用方式,要不就是老版本的redis结构,干脆我就自己看源码瞅瞅怎么个事。 本文主要说明的是数据结构和hash的基本操作原理,不是API文档,有想知道的API请自行查阅文档和代码。 : ziplist、hashtable、listpack、rehash、dict。 先说明 ziplist 和

    2024年02月20日
    浏览(29)
  • redis的hash数据结构底层简记

    hash:k和v都是string的hash表。 HSET(设置集合数据,4.0之前只能设置1个,之后可以设置多个),HSETNX(若k不存在则设置对应v),HDEL(删除指定kv,可以一次删除多个),DEL(删除Hash对象),HMSET(设置多个kv,4.0之后废弃),HGETALL(查找全部数据),HGET(查询k对应的v),HLEN(查

    2024年02月21日
    浏览(26)
  • Redis追本溯源(二)数据结构:String、List、Hash、Set、Zset底层数据结构原理

    Redis 并没有直接用 C 语言的字符串,而是自己搞了一个 sds 的结构体来表示字符串,这个 sds 的全称是 Simple Dynamic String,翻译过来就是“简单的动态字符串”。 安全的二进制存储 资源。关于sds的扩容和缩容下面会进行详细的介绍,这里先不赘述了。 在一些情况中,我们需要

    2024年02月16日
    浏览(39)
  • 【redis】redis获取hash结构的海量数据,hgetAll、hscan、hkeys 性能大比拼

    根据上一篇文章:【Redis】 redis hash getKey getValue 两个的性能差别 我们知道hgetAll的性能是极差的,然后我们优化成hkeys的,但是hkeys真的好吗? 下面我们来说一下我们的现场,就是现场我们

    2024年01月22日
    浏览(20)
  • Redis的五大数据类型的数据结构

      Redis底层有六种数据类型包括: 简单动态字符串、双向链表、压缩列表、哈希表、跳表和整数数组 。这六种数据结构五大数据类型关系如下: String:简单动态字符串 List:双向链表、压缩列表 Hash:压缩列表、哈希表 Sorted Set:压缩列表、跳表 Set:哈希表、整数数组   

    2024年02月11日
    浏览(32)
  • Redis - 数据类型映射底层结构

    从数据类型上体现就是,同一个数据类型,在不同的情况下会使用不同的编码类型,底层所使用的的数据结构也不相同。 字符串对象的编码可以是 int 、 raw 和 embstr 三者之一。 embstr 编码是专门用于保存简短字符串的一种优化编码方式,与 raw 编码会调用两次内存分配函数分

    2023年04月21日
    浏览(29)
  • Redis的数据类型及对应的数据结构(二)

    接上篇:Redis的数据类型及对应的数据结构(一)_鱼跃鹰飞的博客-CSDN博客 本篇主要讨论剩下的几种数据结构的应用场景 应用场景 集合的主要几个特性,无序、不可重复、支持并交差等操作。 因此 Set 类型比较适合用来数据去重和保障数据的唯一性,还可以用来统计多个集

    2024年02月10日
    浏览(71)
  • 深入学习 Redis - 常用数据类型,结构认识

    目录 一、Redis数据类型  Redis 数据类型结构简单认识 每个数据类型具体的编码方式 1.string  2.hash 3.list 4.set 5.zset 典中典:记数字!!! 6.查看 key 对应 value  的实际编码方式 如果本文有帮助到你,不妨给个三连吧~ Redis 中所有的 key 都是 string 类型,不同的是 value 的数据类型

    2024年02月16日
    浏览(41)
  • Redis数据结构:高频面试题及解析

    Redis 是速度非常快的非关系型(NoSQL)内存键值数据库,可以存储键和五种不同类型的值之间的映射。 键的类型只能为字符串,值支持五种数据类型:字符串、列表、集合、散列表、有序集合。 Redis 支持很多特性,例如将内存中的数据持久化到硬盘中,使用复制来扩展读性能

    2024年02月08日
    浏览(51)
  • Redis核心数据结构实战与高性能解析

    目录 一、安装Redis 二、Redis线程与高性能 2.1 Redis是单线程么? 2.2 Redis读写是单线程为何这么快? 2.3 Redis如何处理并发操作命令? 三、核心数据结构实战 3.1 字符串常用操作实战 SET 存入键值对 SETNX SETEX MSET 批量存入键值对 MSETNX DECR 原子减1 DECRBY 原子减 INCR 原子加1 INCRBY 原子

    2024年02月07日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包