💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# 哈希表 [TOC=2,3] `REDIS_HASH` (哈希表)是 [HSET](http://redis.readthedocs.org/en/latest/hash/hset.html#hset "(in Redis 命令参考 v2.8)") 、 [HLEN](http://redis.readthedocs.org/en/latest/hash/hlen.html#hlen "(in Redis 命令参考 v2.8)") 等命令的操作对象,它使用 `REDIS_ENCODING_ZIPLIST` 和 `REDIS_ENCODING_HT` 两种编码方式: ![digraph redis_hash { node [shape=plaintext, style = filled]; edge [style = bold]; // type REDIS_HASH [label="哈希表\nREDIS_HASH", fillcolor = "#95BBE3"]; // encoding REDIS_ENCODING_ZIPLIST [label="压缩列表\nREDIS_ENCODING_ZIPLIST", fillcolor = "#FADCAD"]; REDIS_ENCODING_HT [label="字典\nREDIS_ENCODING_HT", fillcolor = "#FADCAD"]; // edge REDIS_HASH -> REDIS_ENCODING_ZIPLIST; REDIS_HASH -> REDIS_ENCODING_HT; // datastruct 1 ziplist [label="ziplist"]; REDIS_ENCODING_ZIPLIST -> ziplist; // datastruct 2 dict [label="dict.h/dict"]; REDIS_ENCODING_HT -> dict;}](https://box.kancloud.cn/2015-09-13_55f4effc77b77.svg) ### 字典编码的哈希表 当哈希表使用字典编码时,程序将哈希表的键(key)保存为字典的键,将哈希表的值(value)保存为字典的值。 哈希表所使用的字典的键和值都是字符串对象。 下图展示了一个包含三个键值对的哈希表: ![digraph db { rankdir = LR; node [shape = record, style = filled]; edge [style = bold]; dict [label = "<head>dict\n |<number>StringObject\n \"number\" | NULL |<book>StringObject\n \"book\" |<message>StringObject\n \"message\"", fillcolor = "#A8E270"]; number [label = "<head>StringObject | 10086"]; book [label = "<head>StringObject | \"Mastering C++ in 21 days\""]; message [label = "<head>StringObject | \"hello moto\""]; dict:number -> number:head; dict:book -> book:head; dict:message -> message:head;}](https://box.kancloud.cn/2015-09-13_55f4effc870e1.svg) ### 压缩列表编码的哈希表 当使用 `REDIS_ENCODING_ZIPLIST` 编码哈希表时,程序通过将键和值一同推入压缩列表,从而形成保存哈希表所需的键-值对结构: ~~~ +---------+------+------+------+------+------+------+------+------+---------+ | ZIPLIST | | | | | | | | | ZIPLIST | | ENTRY | key1 | val1 | key2 | val2 | ... | ... | keyN | valN | ENTRY | | HEAD | | | | | | | | | END | +---------+------+------+------+------+------+------+------+------+---------+ ~~~ 新添加的 key-value 对会被添加到压缩列表的表尾。 当进行查找/删除或更新操作时,程序先定位到键的位置,然后再通过对键的位置来定位值的位置。 ### 编码的选择 创建空白哈希表时,程序默认使用 `REDIS_ENCODING_ZIPLIST` 编码,当以下任何一个条件被满足时,程序将编码从 `REDIS_ENCODING_ZIPLIST` 切换为 `REDIS_ENCODING_HT` : - 哈希表中某个键或某个值的长度大于 `server.hash_max_ziplist_value` (默认值为 `64` )。 - 压缩列表中的节点数量大于 `server.hash_max_ziplist_entries` (默认值为 `512` )。 ### 哈希命令的实现 哈希类型命令的实现全都是对字典和压缩列表操作函数的包装,以及几个在两种编码之间进行转换的函数,没有特别要讲解的地方。