Redis常用数据结构和存储结构-Hash
2021/7/21 2:06:14
本文主要是介绍Redis常用数据结构和存储结构-Hash,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
redis数据类型
String、Hash、Set、List、ZSet、Hyperloglog、Geo、Streams
2. Hash 哈希
内部结构,结合String的图,只是ptr指向其它数据结构,type为HASH
redis的哈希对象的底层存储可以使用ziplist(压缩列表)和hashtable。当hash对象可以同时满足一下两个条件时,哈希对象使用ziplist编码。
哈希对象保存的所有键值对的键和值的字符串长度都小于64字节
哈希对象保存的键值对数量小于512个
ziplist
redis ziplist数据结构
ziplist的数据结构主要包括两层,ziplist和zipEntry。
ziplist包括zip header、zip entry、zip end三个模块。
zip entry由prevlen、encoding&length、value三部分组成。
prevlen主要是指前面zipEntry的长度,coding&length是指编码字段长度和实际- 存储value的长-
度,value是指真正的内容。 每个key/value存储结果中key用一个zipEntry存储,value用一个zipEntry存储。
每当有新的键值对加入到压缩列表时,程序会先将保存了键的压缩列表节点推入到压缩列表的表尾,然后再将保存了值的压缩列表节点推入到表尾。因此,保存了同一键值对的两个节点总是挨在一起。保存键的节点在前,保存值的节点在后。先添加到压缩列表的键值对放在表头方向,而后来添加的键值对放在表尾方向。
hashtable
压缩列表数据结构,从最底层到最高层dictEntry - dictht - dict
代码结构
/*Hash表一个节点包含Key,Value数据对 */ typedef struct dictEntry { void *key; union { void *val; uint64_t u64; int64_t s64; double d; } v; struct dictEntry *next; /* 指向下一个节点, 链接表的方式解决Hash冲突 */ } dictEntry; /* 存储不同数据类型对应不同操作的回调函数 */ typedef struct dictType { unsigned int (*hashFunction)(const void *key); void *(*keyDup)(void *privdata, const void *key); void *(*valDup)(void *privdata, const void *obj); int (*keyCompare)(void *privdata, const void *key1, const void *key2); void (*keyDestructor)(void *privdata, void *key); void (*valDestructor)(void *privdata, void *obj); } dictType; typedef struct dictht { dictEntry **table; /* dictEntry*数组,Hash表 */ unsigned long size; /* Hash表总大小 */ unsigned long sizemask; /* 计算在table中索引的掩码, 值是size-1 */ unsigned long used; /* Hash表已使用的大小 */ } dictht; typedef struct dict { dictType *type; void *privdata; dictht ht[2]; /* 两个hash表,rehash时使用*/ long rehashidx; /* rehash的索引, -1表示没有进行rehash */ int iterators; /* */ } dict;
为什么定义两个dictht(两个hash表)?
redis默认使用ht[0],ht[1] 不会初始化和分配空间。
如果hash表节点数过多,就需要进行扩容。redis里这种操作叫rehash rehash步骤:
- 为ht[1]分配空间
- 将ht[0]的数据迁移到ht[1]上
- 释放ht[0]的空间
优点
- 相关值存储在一个key中,节省内存空间
- 只使用一个key,减少key冲突
- 需要批量获取值时,只需要一个命令,减少IO
缺点
- 不能给单独一个field设置过期时间
- field多时,无法分布到多个节点
操作命令
1 HDEL key field2 [field2] 删除一个或多个哈希表字段
2 HEXISTS key field 查看哈希表 key中,指定的字段是否存在。
3 HGET key field 获取存储在哈希表中指定字段的值
4 HGETALL key获取在哈希表中指定 key 的所有字段和值
5 HINCRBY key field increment 为哈希表 key中的指定字段的整数值加上增量 increment 。
6 HINCRBYFLOAT key field increment 为哈希表 key中的指定字段的浮点数值加上增量 increment 。
7 HKEYS key 获取所有哈希表中的字段
8 HLEN key获取哈希表中字段的数量
9 HMGET key field1 [field2] 获取所有给定字段的值
10 HMSET key field1 value1 [field2 value2 ] 同时将多个 field-value (域-值)对设置到哈希表 key 中。
11 HSET key field value 将哈希表 key 中的字段 field 的值设为 value 。
12 HSETNX key field value 只有在字段 field 不存在时,设置哈希表字段的值。
13 HVALS key 获取哈希表中所有值
14 HSCAN key cursor [MATCH pattern] [COUNT count] 迭代哈希表中的键值对。
这篇关于Redis常用数据结构和存储结构-Hash的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-08阿里云Redis项目实战入门教程
- 2024-11-08阿里云Redis资料:新手入门与初级使用指南
- 2024-11-08阿里云Redis教程:新手入门及实用指南
- 2024-11-07阿里云Redis学习入门:新手必读指南
- 2024-11-07阿里云Redis学习入门:从零开始的操作指南
- 2024-11-07阿里云Redis学习:初学者指南
- 2024-11-06阿里云Redis入门教程:轻松搭建与使用指南
- 2024-11-02Redis项目实战:新手入门教程
- 2024-10-22Redis入门教程:轻松掌握数据存储与操作
- 2024-10-22Redis缓存入门教程:快速掌握Redis缓存基础知识