一个散列由多个域值对组成,散列的域和值都可以是文字、整数、浮点数或者二进制数据。同一个散列里面的每个域必须是独一无二、互不相同的,而域的值则没有这一要求,换句话说,不同域的值可以是重复的。通过命令,用户可以对散列执行设置域值对、获取域的值、检查域是否存在等操作,也可以让Redis返回散列包含的所有域、所有值或者所有域值对。
一、基本操作
1.关联域值对
HSET key field value
在散列键key中关联给定的域值对field和value。如果域field之前没有关联值,那么命令返回1;如果域field已经有关联值,那么命令用新值覆盖旧值,并返回0。
复杂度为O(1)。
2.获取域关联的值
HGET key field
返回散列键key中,域field所关联的值。如果域field没有关联值,那么返回nil。
复杂度O(1)。
3.仅当域不存在时,关联域值对
如果散列键key中,域field不存在,那么关联给定的域值对field和value。如果域field已经有与之相关联的值,那么命令不做动作。
复杂度O(1)。
4.检查域是否存在
HEXISTS key field
查看散列键key中,给定域field是否存在:存在返回1,不存在返回0。
复杂度为O(1)。
5.删除给定的域值对
HDEL key field [field...]
删除散列键key中的一个或多个指定域,以及那些域的值。不存在的域将被忽略。命令返回被成功删除的域值对数量。
复杂度为O(N),N为被删除的域值对数量。
6.获取散列包含的键值对数量
HLEN key
返回散列键key包含的域值对数量。
复杂度为O(1)。
二、批量操作
1.一次设置或获取散列中的多个域值对
命令 | 效果 | 复杂度 |
HMSET key field value [field value...] | 在散列键key中关联多个域值对,相当于同时执行多个HSET。 | O(N),N为输入的域值对数量。 |
HMGET key field [field...] | 返回散列键key中,一个或过个域值,相当于同时执行多个HGET。 | O(N),N为输入域数量。 |
2.获取散列包含的所有域、值、或者域值对
命令 | 效果 | 复杂度 |
HKEYS key | 返回散列键key包含的所有域。 | O(N),N为被返回域的数量。 |
HVALS key | 返回散列键key中,所有域的值。 | O(N),N为被返回值的数量。 |
HGETALL key | 返回散列键key包含的所有域值对。 | O(N),N为被返回域值对的数量。 |
三、数字操作
对域的值执行自增操作。
命令 | 作用 | 复杂度 |
HINCRBY key field increment | 为散列键key中,域field的值加上整数增量increment。 | O(1) |
HINCRBYFLOAT key field increment | 为散列键key中,域field的值加上浮点数增量increment。 | O(1) |
四、散列键和字符串键
1.命令比较
散列命令 | 字符串/数据库命令 |
HSET | SET |
HGET | GET |
HSETNX | SETNX |
HDEL | DEL |
HMSET | MSET |
HMGET | MGET |
HINCRBY | INCRBY |
HINCRBYFLOAT | INCRBYFLOAT |
HEXISTS | EXISTS |
我们可以发现,字符串键和散列键是如此的类似,那么有了字符串键,散列键的存在意义是什么呢?
2.使用散列的好处
(1)散列可以让我们将一些相关的信息存储在同一个地方,怎么理解呢,因为它们具有相同的键值,而不是直接分散地存储在整个数据库里面,这不仅方便了数据库管理,还可以尽量避免误操作发生。
如图:使用字符串键,则他们分散存储在整个数据库里,若使用散列键,则他们有一个统一的键message。
(2)避免了键名冲突,利用键名来做命名空间。
(3)在一般情况下,保存相同数量的键值对信息,使用散列键比使用字符串键更节约内存。因为Redis管理键需要附加的信息,散列键可以比使用字符串键创建的键的数量少,另外当散列键中域的数量比较少时,redis会自动使用一种占用内存非常少的内存结构来做散列的底层实现。
如图:明显得可以看出使用字符串键所存储的键的数量要比散列键的键的数量多。
所以,只要有可能的话,就尽量使用散列键而不是字符串键来存储键值对数据,因为散列键管理方便、能够避免键名冲突、并且还能够节约内存。
例外情况:想要使用二进制位操作命令;使用键过期命令。