Redis.散列


散列

  • 散列的基本操作
  • 散列的优点
  • 常见应用场景

一个散列由多个域值对(field-value pair)组成,散列的域和值都可以是文字、整数、浮点数或者二进制数据。
同一个散列里面的每个域必须是独一无二、各不相同的,而域的值则没有这一要求,换句话说,不同域的值可以是重复的。
通过命令,用户可以对散列执行设置域值对、获取域的值、检查域是否存在等操作,也可以让 Redis 返回散列包含的所有域、所有值或者所有域值对。

散列的基本操作

关联域值对、获取域的值、检查域是否存在、获取域值对的数量,等等。

HSET key field value

关联域值对
在散列键 key 中关联给定的域值对 field 和 value 。如果域 field 之前没有关联值,那么命令返回 1;如果域 field
已经有关联值,那么命令用新值覆盖旧值,并返回 0。复杂度为 O(1) 。

HGET key field

获取域关联的值
返回散列键 key 中,域 field 所关联的值。如果域 field 没有关联值,那么返回 nil。复杂度为 O(1)。

HSETNX key field value

仅当域不存在时,关联域值对
如果散列键 key 中,域 field 不存在(也即是,还没有与之相关联的值),那么关联给定的域值对 field 和value 。
如果域 field 已经有与之相关联的值,那么命令不做动作。复杂度为 O(1) 。

HEXISTS key field

检查域是否存在
查看散列键 key 中,给定域 field 是否存在:存在返回 1 ,不存在返回 0 。复杂度为 O(1) 。

HDEL key field [field …]

删除给定的域值对
删除散列键 key 中的一个或多个指定域,以及那些域的 值。不存在的域将被忽略。命令返回被成功 删除的域值对数量。复杂度为 O(N) ,N
为被删除的域值对数量。

HLEN key

获取散列包含的键值对数量
返回散列键 key 包含的域值对数量。复杂度为 O(1) 。

HMSET key field value [field value …]

在散列键 key 中关联多个域值对,一次设置或获取散列中的多个域值对,相当于同时执行多个 HSET。
复杂度为 O(N) ,N 为输入的域值对数量。

HMGET key field [field …]

返回散列键 key 中,一个或多个域的值,相当于同时执行多个 HGET 。
复杂度为 O(N) , N 为输入的域数量。

获取散列包含的所有域、值、或者域值对

命令作用复杂度
HKEYS key返回散列键 key 包含的所有域。 O(N),N 为被返回域的数量。
HVALS key返回散列键 key 中,所有域的值。 O(N),N 为被返回值的数量。
HGETALL key返回散列键 key 包含的所有域值对。 O(N),N 为被返回域值对的数量。

和字符串键的值一样,在散列里面,域的值也可以被解释为数字,并执行相应的数字操作。

对域的值执行自增操作

虽然 Redis 没有提供与以上两个命令相匹配的 HDECRBY 命令和 HDECRBYFLOAT 命令,但我们同样可以通过将 increment 设为负数来达到做减法的效果。

命令作用复杂度
HINCRBY key field increment为散列键key中,域field的值加上整数增量 increment 。O(1)
HINCRBYFLOAT key field increment为散列键key中,域field的值加上浮点数增量 increment 。O(1)

散列键和字符串键效果类似的命令

散列命令字符串/数据库命令
HSETSET
HGETGET
HSETNXSETNX
HDELDEL(不仅限于字符串键)
HMSETMSET
HMGETMGET
HINCRBYINCRBY
HINCRBYFLOATINCRBYFLOAT
HEXISTSEXISTS(不仅限于字符串键)

散列的优点

  • 将数据放到同一个地方
散列可以让我们将一些相关的信息储存在同一个地方,而不是直接分散地 储存在整个数据库里面,这不仅方便了数据管理,还可以尽量避免误操作发生。
  • 避免键名冲突
在介绍字符串键的时候,我们说过,可以在命名键的时候,使用分割符来避免命名冲突,但更好的办法是直接使用散列键来储存键值对数据。

**
使用字符串键的数据库创建的键数量多,而使用散列键的数据库创建的键数量则少。随着域数量的增加,使用散列会比使用字符串少创建很多数据库键。**

  • 减少内存占用

    • 在一般情况下,保存相同数量的键值对信息,使用散列键比使用字符串键更节约内存。
    • 因为在数据库里面创建的每个键都带有数据库附加的管理信息(比如这个键的类型、最后一次被访问的时间等等),所以数据库里面的键越多,服务器在储存附加管理信息方面耗费的内存就越多,花在管理数据库键上的
      CPU 也会越多。
    • 除此之外,当散列包含的域值对数量比较少的时候,Redis 会自动使用一种占用内存非常少的数据结构来做散列的底层实现,在散列的数量比较多的时候,这一措施对减少内存有很大的帮助。

只要有可能的话,就尽量使用散列键而不是字符串键来储存键值对数据,因为散列键管理方便、能够避免键名冲突、并且还能够节约内存。

一些没办法使用散列键来代替字符串键的情况:

  • 使用二进制位操作命令:因为 Redis 目前支持对字符串键进行 SETBIT、GETBIT、BITOP 等操作,如果你想使用这些操作,那么只能使用字符串键。
  • 使用过期功能:Redis 的键过期功能目前只能对键进行过期操作,而不能对散列的域进行过期操作,因此如果你要对键值对数据使用过期功能的话,那么只能把键值对储存在字符串里面。

常见应用场景

数据行缓存

有时页面上的某个板块,数据往往来源于数据库查询结果,有时甚至是若干次数据库查询,再经过计算统计后的数据结果
如果请求的比较频繁,将会给数据库带来巨大的压力,为了减轻负载,可以对数据结果进行缓存,并不定期地对这些缓存进行更新
这些从数据库取出来的行数据结构正好对应Redis的散列,常见以 前缀:id 为key,存储数据行到散列

声明:Rock 版权所有,内容均为原创,欢迎转载。

转载:转载请注明原文链接 - Redis.散列


我是一个程序员,致力于网页开发,我还很年轻,什么也不懂。