当前位置:首页 > 问答 > 正文

Redis里头搞懂Hash到底是啥,顺便聊聊怎么查hash数据那些事儿

说到Redis里的Hash,你可以把它想象成我们现实生活中用的一个“档案袋”或者“个人信息表”,你有一个大文件夹(在Redis里就是那个Hash的键),这个文件夹里面装的不是一堆杂乱无章的文件,而是一张张格式固定的表格,每张表格都有一个特定的栏目名(在Redis里叫field,字段)和对应填写的具体内容(value,值)。

(来源:Redis官方文档对Hash数据类型的描述,将其定义为由字段值对组成的映射表)

举个例子就特别清楚了,比如我们要在Redis里存一个用户“张三”的信息,如果用普通的键值对来存,你可能会这样:

  • 键:user:10001:name,值:张三
  • 键:user:10001:age,值:28
  • 键:user:10001:city,值:北京

这样一来,光是张三一个人的信息,你就用了三个键,用户一多,键的数量就会爆炸,管理起来也麻烦。

但如果用Hash,就清爽多了,我们创建一个键,比如叫 user:10001,它的类型是Hash,这个“档案袋”里面,我们就可以这样存:

  • 字段(field)name 对应值(value)张三
  • 字段(field)age 对应值(value)28
  • 字段(field)city 对应值(value)北京

你看,现在张三的所有相关信息都被整齐地归类到了一个键 user:10001 下面,这种方式特别适合用来表示一个对象,因为对象通常就有多个属性。

(来源:Redis实战中常见的用例,即使用Hash来存储对象数据)

那接下来,重点聊聊怎么查这个Hash里的数据。 Redis提供了一系列命令来操作Hash,都很直白。

  1. 往里面塞数据: 主要用 HSET 命令。

    Redis里头搞懂Hash到底是啥,顺便聊聊怎么查hash数据那些事儿

    • HSET user:10001 name 张三 age 28 city 北京
    • 这一条命令就能一次性把三个字段都设置进去,你也可以分开设置,HSET user:10001 name 张三
  2. 取单个字段的值:HGET 命令。

    • 你想知道张三多大了,就查:HGET user:10001 age
    • Redis会直接返回 28 给你,这就像你打开档案袋,直接翻到“年龄”那一栏看具体数字。
  3. 取所有字段和值:HGETALL 命令。

    • 如果你想知道张三这个档案袋里到底装了啥,就用:HGETALL user:10001
    • Redis会把你这个Hash里所有的字段和值一对一对地都列出来,返回结果大概是:1) "name" 2) "张三" 3) "age" 4) "28" 5) "city" 6) "北京",这个命令非常强大,能让你看到这个对象的全貌。
  4. 只取所有字段名:HKEYS 命令。

    • 你只想看看档案袋里有哪些栏目(比如有没有“性别”这一栏),而不关心具体内容,就用:HKEYS user:10001
    • 它会返回:1) "name" 2) "age" 3) "city"
  5. 只取所有值:HVALS 命令。

    • 如果你只关心栏目里填了什么,不关心栏目名,就用:HVALS user:10001
    • 它会返回:1) "张三" 2) "28" 3) "北京"
  6. 检查某个字段是否存在:HEXISTS 命令。

    Redis里头搞懂Hash到底是啥,顺便聊聊怎么查hash数据那些事儿

    • 你想确认一下有没有给张三记录邮箱,可以用:HEXISTS user:10001 email
    • 如果存在,返回 1;不存在,返回 0,这比直接用 HGET 去取,发现是空值再来判断要更高效。
  7. 批量获取多个字段的值:HMGET 命令。

    • 你只想看张三的“名字”和“城市”,不想看全部,可以用:HMGET user:10001 name city
    • 它会返回:1) "张三" 2) "北京",这在网络传输上比用 HGETALL 更节省,因为你只获取了你需要的数据。

(来源:以上所有命令均可在Redis官方命令文档中找到详细定义和示例)

最后简单说说Hash的好处和一点需要注意的地方。

最大的好处就是节省空间操作方便,因为Redis在底层存储一个Hash键时,如果这个Hash很小,它会采用一种非常紧凑的编码方式,比你把每个字段都存成一个独立的键要节省很多内存,操作方便体现在,你可以用一条命令操作这个对象(Hash)的多个属性。

那点需要注意的地方是,虽然Hash很强大,但不建议你把一个Hash弄得特别巨大,比如里面有几万几十万个字段,因为当你使用 HGETALL 这种命令时,可能会因为数据量太大而阻塞Redis一段时间,影响其他请求,对于超大的对象,可能需要考虑拆分成多个Hash,或者使用其他数据结构。

Redis的Hash就是一个“档案袋”,是存储结构化数据(比如用户信息、商品信息、配置项)的利器,查数据的方式也很符合直觉,基本上你想怎么查(查单个、查全部、查部分),都有对应的简单命令来实现。