• 图解Redis 06 | Hash数据类型的原理及应用场景


    介绍

    Hash 类型特别适合存储对象,例如用户信息等。

    String类型也可以用于存储用户信息,Hash与String存储用户信息的区别如下图所示:

    内部实现

    Hash 类型 的底层数据结构是通过压缩列表(Ziplist)或哈希表(Hash Table)实现的:

    • 如果 Hash 类型的元素个数小于 512(默认值,可通过配置 hash-max-ziplist-entries 调整),并且所有值都小于 64 字节(默认值,可通过配置 hash-max-ziplist-value 调整),Redis 会使用压缩列表作为底层数据结构。

    • 如果Hash类型的元素不满足上述条件,那么Redis将会使用哈希表作为Hash类型的底层数据结构。

      在 Redis 7.0 版本中,压缩列表数据结构已经被废弃,取而代之的是 Listpack 数据结构。Listpack 是一种新的压缩数据结构,其目的是提供更好的性能和更高的存储效率。

    常用命令

    插入单个元素。
    hset key field value
    
    #示例
    > hset myhash k1 v1
     1 
    > hset myhash k2 v2
     1
    
    查询单个元素。
    hget key field
    
    #示例
    > hget myhash k2
    “v2”
    
    当某个key不存在时,插入数据。
    hsetnx key field value
    
    #示例
    > hsetnx myhash k3 v3
    (integer) 1
    > hget myhash k3
    "v3"
    

    如果尝试插入一个已存在的键,则原始值将不会改变,如下例所示:

    > hsetnx myhash k3 val3
    (integer) 0
    > hget myhash k3
    "v3"
    
    删除键中的一个或多个元素。
    hdel myhash field [field …]
    
    #示例
    > hdel myhash k1 v1
    (integer) 1
    

    注意:hdel 命令只用于从哈希表中删除一个或多个特定的字段,但它不会删除整个key。如果你想删除整个哈希表,你应该使用 del 命令。

    累加某个整数类型的字段值。
    hincrby key field increment
    
    #示例
    > hset myhash k4 4
    1
    > hincrby myhash k4 2
    (integer) 6
    > hget myhash k4
    "6"
    

    更多操作命令,详见文章末尾。

    应用场景

    购物车

    以用户id为key,以商品sku id为field,以商品数量为value刚好构成了购物车的三个要素,如下图所示。

    涉及的命令如下:

    #将商品添加到购物车中,{user_id} 是用户的ID,{sku_id} 是商品的SKU ID,1 是初始数量。
    HSET cart:{user_id} {sku_id} 1
    
    # 增加购物车中某个商品的数量
    HINCRBY cart:{user_id} {sku_id} 1
    
    # 统计购物车中商品的总数量,即购物车中包含多少个不同的商品。
    HLEN cart:{user_id}
    
    # 删除商品
    HDEL cart:{user_id} {sku_id}
    
    # 获取购物车中所有商品信息
    HGETALL cart:{user_d}
    

    然而,需要注意的是,这里Redis仅保存了商品SKU ID和数量,而商品的完整信息(如名称、价格、描述等)需要通过商品ID去数据库中查询,以便展示完整的商品信息。

    缓存对象

    Hash 类型的 (key, field, value) 结构与对象的 (objectid, attribute, value) 结构类似,因此也可以用于存储对象。

    我们以用户信息为例,其在关系数据库中的结构是这样的:

    我们可以使用下面的命令将用户对象的信息存储到Hash类型中:

    > HMSET uid:1 name Jerry age 20
    OK
    
    > HMSET uid:2 name Tom age 20
    OK
    
    > HGETALL uid:1
    1) "name"
    2) "Jerry"
    3) "age"
    4) "20"
    

    在介绍String类型的应用场景的时候已经介绍过了,String+Json也是一种存储对象的方式,那么在存储对象的时候,到底应该用String+json还是Hash呢?

    String + JSON:这种方式将整个对象序列化为一个 JSON 字符串,存储在 Redis 的 String 类型中。这种方法适用于对象结构复杂且整体更新较少的情况。

    Hash:这种方式将对象的每个属性存储为 Hash 类型的字段值对。这种方法适用于对象中一些属性频繁变化的情况。

    更多hash操作命令

    1. 查询一个或多个字段值。
    hmget key field [field …]
    
    > hmget uid:1 name age
    1) "Jerry"
    2) "20"
    
    2. 查询某个key的所有字段。
    hkeys key
    
    > hkeys uid:1
    1) "name"
    2) "age"
    
    3. 查询某个键的所有字段值。
    hvals key
    
    > hvals uid:1
    1) "Jerry"
    2) "20"
    
    4. 对某个浮点型字段进行累加。
    hincrbyfloat key field increment
    
    > hset floathash k1 1.2
    1
    > hincrbyfloat floathash k1 2.2
    3.4
    
    5. 查询某个字段是否存在。
    hexists key field
    
    > hexists  floathash k1
    (integer) 1
    
  • 相关阅读:
    JCMsuite应用—单光子光源耦合至光纤
    【LeetCode-中等题】34. 在排序数组中查找元素的第一个和最后一个位置
    Spring Security认证之基本认证
    计算机操作系统详解
    【kali-Metasploit】Armitage常见问题:sudo权限、连接不到数据库、service not found
    CMake Cookbook
    【FreeRTOS(十三)】任务通知
    gin通过文件流提供流式下载文件,golang
    华为云Stack的学习(五)
    当transcational遇上synchronized
  • 原文地址:https://blog.csdn.net/weixin_42627385/article/details/143318235