【redis】hash基本命令和内部编码
文章目录
- 表示形式
- 命令
- HSET 和 HGET
- HEXISTS
- HDEL
- HKEYS
- HVALS
- HGETALL
- HMGET
- HLEN
- HSETNX
- HINCRBY
- HINCRBYFLOAT
- 命令小结
- 内部编码
表示形式
Redis
自身已经是键值对结构了
Redis
自身的键值对就是通过哈希的方式来组织的
把 key
这一层组织完成之后,到了 value
这一层,value
这一层也可以是哈希
- 哈希类型中的映射关系通常称为
field-value
,用于区分Redis
整体的键值对(key-value
),注意这里的value
是指field
对应的值,不是 key 对应的值,注意value
在不同上下文的作用
命令
HSET 和 HGET
设置/获取 hash
中指定的字段(field
)的值(value
)
语法:
HSET key field value [field value...]
HGET key field
HSET
的返回值是设置成功的键值对(field-value
)的个数- 时间复杂度:
O
(
1
)
O(1)
O(1)
HEXISTS
判断 hash
中是否有指定的字段
语法:
HEXISTS key field
- 返回值:
1
表示存在,0
表示不存在 - 时间复杂度:
O
(
1
)
O(1)
O(1)
HDEL
删除 hash
中指定的字段
del
删除的是key
hdel
删除的是field
语法:
HDEL key field [field...]
- 返回值是本次删除的字段个数
- 时间复杂度:删除一个元素为
O
(
1
)
O(1)
O(1),删除
N
N
N 个位
O
(
N
)
O(N)
O(N)(几十几百个就视为 1)
HDEL
是删除key
对应的value
(field-value
) 中的键值对field
DEL
是直接删除key
对应的value
(里面所有的键值对全删)
HKEYS
获取 hash
中的所有字段
语法:
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 表示:
Redis
整体key
的个数- 当前命令中
key
的个数 (因为我们一般不会弄太多key
,所以一般可以直接看做 O ( 1 ) O(1) O(1))- 当前
key
对应的value
里面的元素个数- …
HVALS
获取 hash 中的所有的值
语法:
HVALS key
- 时间复杂度:
O
(
N
)
O(N)
O(N)(
N
N
N 是哈希的元素个数,如果哈希非常大,这个操作就可能导致
Redis
服务器被阻塞住)
HGETALL
获取 hash
中的所有字段以及对应的值
- 相当于结合了
HKEYS
和HVALS
语法:
HGETALL key
- 时间复杂度:
O
(
N
)
O(N)
O(N)(
N
N
N 是哈希的元素个数,如果哈希非常大,这个操作就可能导致
Redis
服务器被阻塞住)
这个操作,还是风险比较大。多数情况下,不需要查询所有的
field
,可能只查其中的几个key
HMGET
一次获取 hash
中多个字段的值
语法:
HMGET key field [field...]
- 时间复杂度:删除一个元素为 O ( 1 ) O(1) O(1),删除 N N N 个位 O ( N ) O(N) O(N)(几十几百个就视为 1)
- 返回值:字段对应的值或者
nil
- 上述
HKEYS
、HVALS
、HGETALL
都是存在一定风险的。hash
元素个数太多,执行的时间就会比较长,从而阻塞Redis
- 一条命令,就能完成所有的遍历操作
HSCAN
遍历Redis
的hash
,“渐进式遍历“
- 敲一次命令,遍历一小部分
- 再敲一次命令,再遍历一小部分
- …
- 连续执行多次,就可以完成整个遍历过程(化整为零)
ConcurrentHashMap
线程安全的哈希表
HLEN
获取 hash
中的所有字段的个数
语法:
HLEN key
- 时间复杂度: O ( 1 ) O(1) O(1)
- 返回值:字段个数
HSETNX
在字段不存在的情况下,设置 hash
中的字段和值
语法:
HSETNX key field value
- 时间复杂度: O ( 1 ) O(1) O(1)
- 返回值:1 表示成功,0 表示失败
HINCRBY
将 hash
中字段对应的数字添加指定的值
语法:
HINCRBY key field increment
- 时间复杂度: O ( 1 ) O(1) O(1)
- 返回值:该字段变化后的值
HINCRBYFLOAT
HINCRBY
的浮点数版本
语法:
HINCRBYFLOAT key field increment
- 时间复杂度: O ( 1 ) O(1) O(1)
- 返回值:该字段变化后的值
命令小结
内部编码
哈希的内部编码有两种:
ziplist
:压缩列表hashtable
:哈希表
压缩:
rar
zip
gzip
7z
- …
这是一些具体的压缩算法。
压缩的本质,是针对数据进行重新编码。不同的数据,有不同的特点,结合这些特点,进行精妙的设计,重新编码之后,就能够缩小体积
比如,现在有字符串:
abcccddddeeeee
- 重新编码表示:
1a2b3c4d5e
- 重新编码后的结果就比原来的短了(粗糙)
ziplist
内部的数据结构也是精心设计的(目的是节省内存空间)
- 表示一个普通的
hash
表,可能会浪费一定的空间(hash
首先是一个数组,数组上有些位置有元素,有些没有元素) - 付出的代价是进行读写元素,速度是比较慢的。如果元素个数少,慢的不明显,但如果元素多了,慢就会雪上加霜
如果:
- 哈希中的元素个数比较少,使用
ziplist
表示;元素较多,就用hashtable
来表示 - 每个
value
的值,长度都比较短,使用ziplist
表示;如果某个value
的长度太长了,也会转换成hashtable
- 可以在
redis。conf
文件中,调整hash-max-ziplist-entries
配置和hash-max-ziplist-value
配置