目录
一、Hash 哈希
几乎所有的主流编程语言都提供了哈希(hash)类型,它们的叫法可能是哈希、字典、关联数
组、映射。在 Redis 中,哈希类型是指值本身又是⼀个键值对结构,形如 key = "key",value = { {
field1, value1 }, ..., {fieldN, valueN } }。
哈希类型中的映射关系通常称为 field-value,⽤于区分 Redis 整体的键值对(key-value),
注意这里的 value 是指 field 对应的值,不是键(key)对应的值,请注意 value 在不同上下
文的作用。
1.2 常用命令
1.2.1 HSET
设置 hash 中指定的字段(field)的值(value)。
语法:
HSET key field value [field value ...]
命令有效版本:2.0.0 之后
时间复杂度:插⼊一组 field 为 O(1), 插入 N 组 field 为 O(N)
返回值:添加的字段的个数。
示例:
redis> HSET myhash field1 "Hello"
(integer) 1
redis> HGET myhash field1
"Hello"
1.2.2 HGET
获取 hash 中指定字段的值。
语法:
HGET key field
命令有效版本:2.0.0 之后
时间复杂度:O(1)
返回值:字段对应的值或者nil
1.2.3 HEXISTS
判断 hash 中是否有指定的字段。
语法:
HEXISTS key field
命令有效版本:2.0.0 之后
时间复杂度:O(1)
返回值:1 表示存在,0 表示不存在。
示例:
redis> HSET myhash field1 "foo"
(integer) 1
redis> HEXISTS myhash field1
(integer) 1
redis> HEXISTS myhash field2
(integer) 0
1.2.4 HDEL
删除 hash 中指定的字段。
语法:
HDEL key field [field ...]
命令有效版本:2.0.0 之后
时间复杂度:删除⼀个元素为 O(1). 删除 N 个元素为 O(N).
返回值:本次操作删除的字段个数。
示例:
redis> HSET myhash field1 "foo"
(integer) 1
redis> HDEL myhash field1
(integer) 1
redis> HDEL myhash field2
(integer) 0
1.2.5 HKEYS
获取 hash 中的所有字段。
语法:
HKEYS key
命令有效版本:2.0.0 之后
时间复杂度:O(N), N 为 field 的个数.
返回值:字段列表。
示例:
redis> HSET myhash field1 "Hello"
(integer) 1
redis> HSET myhash field2 "World"
(integer) 1
redis> HKEYS myhash
1) "field1"
2) "field2
1.2.6 HVALS
获取 hash 中的所有的值。
语法:
HVALS key
命令有效版本:2.0.0 之后
时间复杂度:O(N), N 为 field 的个数.
返回值:所有的值。
示例:
redis> HSET myhash field1 "Hello"
(integer) 1
redis> HSET myhash field2 "World"
(integer) 1
redis> HVALS myhash
1) "Hello"
2) "World"
1.2.7 HGETALL
获取 hash 中的所有字段以及对应的值。
语法:
HGETALL key
命令有效版本:2.0.0 之后
时间复杂度:O(N), N 为 field 的个数.
返回值:字段和对应的值。
示例:
redis> HSET myhash field1 "Hello"
(integer) 1
redis> HSET myhash field2 "World"
(integer) 1
redis> HGETALL myhash
1) "field1"
2) "Hello"
3) "field2"
4) "World"
1.2.8 HMGET
⼀次获取 hash 中多个字段的值.
语法:
HMGET key field [field ...]
命令有效版本:2.0.0 之后
时间复杂度:只查询⼀个元素为 O(1), 查询多个元素为 O(N), N 为查询元素个数.
返回值:字段对应的值或者 nil。
示例:
redis> HSET myhash field1 "Hello"
(integer) 1
redis> HSET myhash field2 "World"
(integer) 1
redis> HMGET myhash field1 field2 nofield
1) "Hello"
2) "World"
3) (nil)
1.2.9 HLEN
获取 hash 中的所有字段的个数。
语法:
HLEN key
命令有效版本:2.0.0 之后
时间复杂度:O(1)
返回值:字段个数。
示例:
redis> HSET myhash field1 "Hello"
(integer) 1
redis> HSET myhash field2 "World"
(integer) 1
redis> HLEN myhash
(integer) 2
1.2.10 HSETNX
在字段不存在的情况下,设置 hash 中的字段和值。
语法:
HSETNX key field value
命令有效版本:2.0.0 之后
时间复杂度:O(1)
返回值:1 表示设置成功,0 表示失败。
示例:
redis> HSETNX myhash field "Hello"
(integer) 1
redis> HSETNX myhash field "World"
(integer) 0
redis> HGET myhash field
"Hello"
1.2.11 HINCRBY
将 hash 中字段对应的数值添加指定的值。
语法:
HINCRBY key field increment
命令有效版本:2.0.0 之后
时间复杂度:O(1)
返回值:该字段变化之后的值
示例:
redis> HSET myhash field 5
(integer) 1
redis> HINCRBY myhash field 1
(integer) 6
redis> HINCRBY myhash field -1
(integer) 5
redis> HINCRBY myhash field -10
(integer) -5
1.2.12 HINCRBYFLOAT
HINCRBY 的浮点数版本。
1.3 内部编码
哈希的内部编码有两种:
ziplist(压缩列表) :当哈希类型元素个数小于 hash-max-ziplist-entries 配置(默认 512 个)、 同时所有值都小于 hash-max-ziplist-value 配置(默认 64 字节)时,Redis 会使用 ziplist 作为哈希的内部实现,ziplist 使用更加紧凑的结构实现多个元素的连续存储,所以在节省内存方面比hashtable 更加优秀。
hashtable(哈希表) :当哈希类型无法满足 ziplist 的条件时,Redis 会使用 hashtable 作为哈希的内部实现,因为此时 ziplist 的读写效率会下降,而 hashtable 的读写时间复杂度为 O(1)。
下⾯的示例演示了哈希类型的内部编码,以及响应的变化。
当field的数量比较少且没有大的value时,内部编码为ziplist:
127.0.0.1:6379> hmset hashkey f1 v1 f2 v2
OK
127.0.0.1:6379> object encoding hashkey
"ziplist"
当有value大于64个字节时,内部编码为hashtable:
127.0.0.1:6379> hset hashkey f3 "one string is bigger than 64 bytes ... 省略..."
OK
127.0.0.1:6379> object encoding hashkey
"hashtable"