在 Redis 中使用哈希(Hash)结构存储数据时,其内部实现涉及两级哈希表(但并非用户直接感知的“一级哈希”和“二级哈希”),而是通过一个全局哈希表和哈希桶内的条目来管理数据。具体来说:
Redis 哈希结构的内部实现:
全局哈希表(字典):
Redis 的所有键值对都存储在一个全局的哈希表中(实际可能有两个,用于渐进式 rehash)。这个哈希表的键是用户设置的 Redis 键(例如user:1000
),而值则指向具体的 Redis 对象(如字符串、列表、哈希对象等)。哈希对象(Hash Object)的存储:
当用户使用哈希结构(例如HSET user:1000 name "Alice"
)时:- 键(Key):
user:1000
(整个哈希结构的键)会被存储在全局哈希表中。 - 值(Value):对应的值是一个 Redis 哈希对象,这个对象内部又维护了一个独立的哈希表(称为字段哈希表),用于存储该哈希结构中的字段和值。
- 键(Key):
字段哈希表的细节:
- 这个内部的字段哈希表(即你提到的“后面的哈希表”)中,同时存储了字段(field)和值(value)。
- 例如,对于
HSET user:1000 name "Alice" age 30
:- 字段哈希表中会存储两个条目:
- 键:`name`,值:`"Alice"`(实际为指向 SDS 字符串的指针)。 - 键:`age`,值:`30`(同样编码为 Redis 对象)。
- 字段哈希表中会存储两个条目:
为什么这样设计?
- 高效访问:通过两级哈希表(全局键→哈希对象,字段→值),可以在 O(1) 时间复杂度内访问任意字段。
- 内存优化:Redis 会根据数据量动态选择编码方式(ziplist 或 hashtable),小哈希会使用 ziplist 压缩存储(但最终仍按逻辑上的键值对存储)。
总结:
- 全局哈希表:存储所有 Redis 键到值的映射(值可能是字符串、列表、哈希对象等)。
- 哈希对象内部的字段哈希表:存储该哈希结构中的所有字段和对应的值(即同时存 field 和 value)。
因此,你提到的“后面的哈希表”中同时存储了字段(field)和值(value)。
内容由零声教学AI助手提供,问题来源于学员提问