13 hash 相关操作

Posted 蓝风9

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了13 hash 相关操作相关的知识,希望对你有一定的参考价值。

前言

相关介绍主要围绕着如下的一些常用的命令, 来看看 hash 相关操作的具体 api 

如下常用的命令来自于我们常见的教程 : https://www.runoob.com/redis/redis-hashes.html 

本文的相关代码 拷贝自 redis-6.2.0  

代码来自于 https://redis.io/ 

数据存储

当数据元素小于等于 hash_max_ziplist_entries(默认为512) 的时候使用的是 ziplist 来存储数据 

超过了 hash_max_ziplist_entries 之后, 数据结构更新为 dict 

HDEL key field1 [field2] - 执行 hdel user name age

这里可以看出的是 参数的数量要求大于等于 3 个, 也就是可以删除同一个 hash 的多个 key 

我们来看一下 hdelCommand 

获取 key 对应的 entry, 并确保类型为 HASH, 返回给客户端错误信息 

遍历 fieldList, 从 entry 里面删除 field 的数据 

如果当前 entry 有改动, 发送 db key 的更新通知 

返回给客户端的是 当前 entry 中删除的 key 的数据 

具体的处理删除 field 的方法如下 

如果 encoding 为 ZIPLIST, 首先找到 field 对应的位置, 删除 field & fieldValue 

如果 encoding 为 HASHTABLE, 从 dict 里面删除 field 对应的 entry  

最终客户端这边展示的结果如下, 返回的是 user 这个 hash 下面删除的元素的数量, 这里删除了 name -> jerry, age -> 77 两个元素  

HEXISTS key field - 执行 hexists user name 

这里可以看出的是 参数的数量要求等于 3 个 

我们来看一下 hexistsCommand 

获取 key 对应的 entry 

判断给定的 field 在 entry 中是否存在 

o 的类型为 HASH, encoding 为 ZIPLIST, ptr 指向了一个 ziplist 

具体的业务处理的方式为 

如果是 ziplist, 获取 field 对应的元素信息, 如果存在 返回 1 

如果是 hashtable, 获取 field 对应的 entry 的信息, 如果存在 返回 1  

最终客户端这边展示的结果如下, 返回的是 user 这个 hash 下面 name 这个 field 是否存在 

HGET key field - 执行 hget user name

这里可以看出的是 参数的数量要求等于 3 个 

我们来看下 hgetCommand 

获取 key 对应的 entry 

获取给定的 field 对应的值 

具体的业务处理的方式为 

如果是 ziplist, 获取 field 对应的元素信息, 返回 field 紧接着的 fieldValue 

如果是 hashtable, 获取 field 对应的 entry 的 value 返回 

这里获取到的是 len 为 5, 数据为 jerrry 

最终客户端这边展示的结果如下, 返回的是 user 这个 hash 下面 name 这个 field 对应的值 

HGETALL key - 执行 hgetall user

这里可以看出的是 参数的数量要求等于 2 个 

我们来看一下 hgetallCommand 

响应元素长度给客户端 

遍历给定的 entry, 响应 key, value 给客户端 

哈希的具体的迭代方式 

创建迭代器, 封装 subject, encoding, 如果是 hashtable, 获取迭代器

迭代数据, 如果 ziplist 编码, 基于 ziplistNext 进行迭代, 如果是 hashtable 编码, 基于 dictNext 进行迭代 

最终客户端这边展示的结果如下, 返回的是 user 这个 hash 下面 field & fieldValue 列表 

HINCRBY key field increment - 执行 hincrby user counter 2

这里可以看出的是 参数的数量要求等于 4 个 

我们来看一下 hincrbyCommand 

这里的相关操作 和字符串的 incr 的相关业务是相同的, 这里不多赘述 

最终客户端这边展示的结果如下, user 这个 entry 下面 counter 不存在, 这里累增了 2, 返回的是 counter 累增之后的结果 2 

HKEYS key - 执行 hkeys user

这里可以看出的是 参数的数量要求等于 2 个 

我们来看一下 hkeysCommand 

同样是类似于上面的 hgetall user 

最终客户端这边展示的结果如下, user 这个 entry 下面 所有的 key 列表 

HLEN key - 执行 hlen user

这里可以看出的是 参数的数量要求等于 2 个 

我们来看一下 hlenCommand 

获取到 key 对应的 entry 

获取 entry 里面元素的数量返回 

元素个数的具体计算方式 

如果编码是 ziplist, 获取 ziplist 的长度 / 2, 即为哈希中元素的数量 

如果编码是 hashtable, 通过 hashtable 相关 元数据 直接获取元素数量 

最终客户端这边展示的结果如下, user 这个 entry 下面元素的数量 

HMGET key field1 [field2]

这里可以看出的是 参数的数量要求大于等于 3 个 

我们来看一下 hmgetCommand 

获取到 key 对应的 entry 

先返回一个结果长度 

再返回 fieldList 对应的所有的 value 列表 

获取 field 对应的 value 的方式就类似于 hget 里面的业务处理了 

最终客户端这边展示的结果如下, user 这个 entry 下面 name, age 对应的 value 列表 

HMSET key field1 value1 [field2 value2] - 执行 hmset user field1 value1 field2 value2

这里可以看出的是 参数的数量要求大于等于 4 个 

我们来看一下 hsetCommand 

需要确认 field, value 是成对出现 

然后 尝试更新存储的数据结构的转换 

循环 fieldList, valueList, 循环设置 field, value 

返回给客户端 创建成功 或者 具体设置的 field, value 对的数量 

发送 db key 的更新通知, 更新 dirty 

设置 field, value 的具体的信息 

如果编码是 ziplist, 查询 field 是否存在, 如果是存在 更新 value, 否则 新增 field, value 

如果编码是 hashtable, 查询 field 对应的 entry 是否存在, 如果是存在 更新 value, 否则 新增 field, value 

最终客户端这边展示的结果如下, user 这个 entry 下面 设置 field1, field2 成功 

HSET key field value 

这里可以看出的是 参数的数量要求大于等于 4 个 

hset, hsetnx 都是差不多, 这里只介绍一个 

这里的具体的实现 就和上面 hmset 的实现是同一套, 这不多赘述 

最终客户端这边展示的结果如下, user 这个 entry 下面 设置 field3, field4 成功 

HVALS user

这里可以看出的是 参数的数量要求大于等于 2 个 

我们看一下 hvalsCommand 

和上面 hgetall 的相关处理业务代码 基本一致, 这里不多赘述 

最终客户端这边展示的结果如下, user 这个 entry 下面所有的 value 列表 

HSCAN key cursor [MATCH pattern] [COUNT count] - 执行 hscan user 0 MATCH * COUNT 1

这里可以看出的是 参数的数量要求大于等于 2 个 

这的迭代类似于 11 key 相关操作 

不过对于这里编码为 ziplist 的情况 COUNT 这两个选项是没用的[这是一个很细的细节] 

迭代的是 ziplist 里面的所有的元素  

最终客户端这边展示的结果如下, user 这个 entry 下面所有的 匹配 pattern 的 field, value 列表 

完 

以上是关于13 hash 相关操作的主要内容,如果未能解决你的问题,请参考以下文章

redis之Hash相关操作

大数据之Redis:Redis数据类型Hash及相关的命令行操作

memcached中hash表相关操作

Redis 数据结构操作相关命令

Redis 数据结构操作相关命令

java操作redis