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 相关操作的主要内容,如果未能解决你的问题,请参考以下文章