【redis】hash基本命令和内部编码

文章目录

表示形式

Redis 自身已经是键值对结构了
Redis 自身的键值对就是通过哈希的方式来组织的

key 这一层组织完成之后,到了 value 这一层,value 这一层也可以是哈希

  • 哈希类型中的映射关系通常称为 field-value,用于区分 Redis 整体的键值对(key-value),注意这里的 value 是指 field 对应的值,不是 key 对应的值,注意 value 在不同上下文的作用

命令

HSET 和 HGET

设置/获取 hash 中指定的字段(field)的值(value


语法:

redis 复制代码
HSET key field value [field value...]

HGET key field
  • HSET 的返回值是设置成功的键值对(field-value)的个数
  • 时间复杂度: O ( 1 ) O(1) O(1)

HEXISTS

判断 hash 中是否有指定的字段


语法:

redis 复制代码
HEXISTS key field
  • 返回值:1 表示存在,0 表示不存在
  • 时间复杂度: O ( 1 ) O(1) O(1)

HDEL

删除 hash 中指定的字段

  • del 删除的是 key
  • hdel 删除的是 field

语法:

redis 复制代码
HDEL key field [field...]
  • 返回值是本次删除的字段个数
  • 时间复杂度:删除一个元素为 O ( 1 ) O(1) O(1),删除 N N N 个位 O ( N ) O(N) O(N)(几十几百个就视为 1)
  • HDEL 是删除 key 对应的 valuefield-value) 中的键值对 field
  • DEL 是直接删除 key 对应的 value(里面所有的键值对全删)

HKEYS

获取 hash 中的所有字段


语法:

redis 复制代码
HKEYS key
  • 这个操作,会先根据 key 找到对应的 hash( O ( 1 ) O(1) O(1)),然后再遍历 hash( O ( N ) O(N) O(N), N N N 为 hash 的元素个数)

谈到 O ( N ) O(N) O(N),有的时候, N N N 表示:

  1. Redis 整体 key 的个数
  2. 当前命令中 key 的个数 (因为我们一般不会弄太多 key,所以一般可以直接看做 O ( 1 ) O(1) O(1))
  3. 当前 key 对应的 value 里面的元素个数
  4. ...

HVALS

获取 hash 中的所有的值


语法:

redis 复制代码
HVALS key
  • 时间复杂度: O ( N ) O(N) O(N)( N N N 是哈希的元素个数,如果哈希非常大,这个操作就可能导致 Redis 服务器被阻塞住)

HGETALL

获取 hash 中的所有字段以及对应的值

  • 相当于结合了 HKEYSHVALS

语法:

redis 复制代码
HGETALL key
  • 时间复杂度: O ( N ) O(N) O(N)( N N N 是哈希的元素个数,如果哈希非常大,这个操作就可能导致 Redis 服务器被阻塞住)

这个操作,还是风险比较大。多数情况下,不需要查询所有的 field,可能只查其中的几个 key

HMGET

一次获取 hash 中多个字段的值


语法:

redis 复制代码
HMGET key field [field...]
  • 时间复杂度:删除一个元素为 O ( 1 ) O(1) O(1),删除 N N N 个位 O ( N ) O(N) O(N)(几十几百个就视为 1)
  • 返回值:字段对应的值或者 nil
  • 上述 HKEYSHVALSHGETALL 都是存在一定风险的。hash 元素个数太多,执行的时间就会比较长,从而阻塞 Redis
    • 一条命令,就能完成所有的遍历操作
  • HSCAN 遍历 Redishash,"渐进式遍历 "
    • 敲一次命令,遍历一小部分
    • 再敲一次命令,再遍历一小部分
    • ...
    • 连续执行多次,就可以完成整个遍历过程(化整为零

ConcurrentHashMap 线程安全的哈希表

HLEN

获取 hash 中的所有字段的个数


语法:

redis 复制代码
HLEN key
  • 时间复杂度: O ( 1 ) O(1) O(1)
  • 返回值:字段个数

HSETNX

在字段不存在的情况下,设置 hash 中的字段和值


语法:

redis 复制代码
HSETNX key field value
  • 时间复杂度: O ( 1 ) O(1) O(1)
  • 返回值:1 表示成功,0 表示失败

HINCRBY

hash 中字段对应的数字添加指定的值


语法:

redis 复制代码
HINCRBY key field increment
  • 时间复杂度: O ( 1 ) O(1) O(1)
  • 返回值:该字段变化后的值

HINCRBYFLOAT

HINCRBY 的浮点数版本


语法:

redis 复制代码
HINCRBYFLOAT key field increment
  • 时间复杂度: O ( 1 ) O(1) O(1)
  • 返回值:该字段变化后的值

命令小结

内部编码

哈希的内部编码有两种:

  1. ziplist:压缩列表
  2. hashtable:哈希表

压缩:

  • rar
  • zip
  • gzip
  • 7z
  • ...
    这是一些具体的压缩算法。

压缩的本质,是针对数据进行重新编码。不同的数据,有不同的特点,结合这些特点,进行精妙的设计,重新编码之后,就能够缩小体积

比如,现在有字符串:abcccddddeeeee

  • 重新编码表示:1a2b3c4d5e
  • 重新编码后的结果就比原来的短了(粗糙)

ziplist 内部的数据结构也是精心设计的(目的是节省内存空间)

  • 表示一个普通的 hash 表,可能会浪费一定的空间(hash 首先是一个数组,数组上有些位置有元素,有些没有元素)
  • 付出的代价是进行读写元素,速度是比较慢的。如果元素个数少,慢的不明显,但如果元素多了,慢就会雪上加霜

如果:

  1. 哈希中的元素个数比较少,使用 ziplist 表示;元素较多,就用 hashtable 来表示
  2. 每个 value 的值,长度都比较短,使用 ziplist 表示;如果某个 value 的长度太长了,也会转换成 hashtable
  • 可以在 redis。conf 文件中,调整 hash-max-ziplist-entries 配置和 hash-max-ziplist-value 配置

相关推荐
A-刘晨阳14 分钟前
【Linux】Redis 6.2.6 的二进制部署【适用于多版本】
linux·运维·redis
程序猿ZhangSir2 小时前
Redis 缓存进阶篇,缓存真实数据和缓存文件指针最佳实现?如何选择?
数据库·redis·缓存
Yasin Chen6 小时前
C# Dictionary源码分析
算法·unity·哈希算法
段帅龙呀10 小时前
Redis构建缓存服务器
服务器·redis·缓存
到底起什么网名才能不重名16 小时前
使用各种CSS美化网页
前端·css·vscode·bootstrap·html
用户83249514173218 小时前
Spring Boot 实现 Redis 多数据库切换(多数据源配置)
redis
傲祥Ax1 天前
Redis总结
数据库·redis·redis重点总结
Orlando cron1 天前
源哈希(sh)解析
负载均衡·哈希算法
都叫我大帅哥1 天前
Redis AOF持久化深度解析:命令日志的终极生存指南
redis
都叫我大帅哥1 天前
Redis RDB持久化深度解析:内存快照的魔法与陷阱
redis