Lecture03-Redis-数据类型-String与Hash

文章目录

    [toc]

    单词词性音标含义
    binaryadj./ˈbaɪnəri/二进制的(Redis String 二进制安全,可存图片、序列化对象等)
    safeadj./seɪf/安全的(不会对存入的二进制数据做重新编码)
    incrv./ɪnˈkr/递增(INCR key 对数字值原子 +1,计数器核心命令)
    decrv./dɪˈkr/递减(DECR key 原子 -1)
    appendv./əˈpend/追加(APPEND key value 在原值末尾追加)
    strlenn./str len/字符串长度(STRLEN key 返回值的长度)
    fieldn./fiːld/字段(Hash 中的子键,类似 Map 的 key)
    hashn./hæʃ/哈希(HSET/HGET 等命令操作 Hash 结构)

    Lecture03-Redis-数据类型-String与Hash

    1、总体结构

    Redis 中的数据总体是键值对,不同数据类型指的是 value 的类型:

    Key  ->  Value
            ┌──────────┐
            │ string   │
            │ list     │
            │ set      │
            │ hash     │
            │ zset     │
            │ 其他     │
            └──────────┘
    

    记忆:一个 Key 对应一个 value;value 长什么样,决定你用哪组命令。


    2、String 类型

    1、什么是 String

    • Redis 最基本的类型,key 对应一个单一字符串值。
    • 二进制安全:存进去是啥样、取出来就是啥样,不会重新编码——所以图片、序列化对象都能存。
    • 单个 value 最大 512MB。

    2、常用命令

    命令功能
    set key value添加/覆盖键值对
    set key value NX仅当 key 不存在时设置(分布式锁基础)
    set key value XX仅当 key 存在时设置
    set key value EX 秒设置时同时指定过期时间(秒)
    get key取 value
    getset key newval设置新值,返回旧值(以新换旧)
    append key value追加到原值末尾
    strlen key返回值的长度
    incr key数字值 +1(原子);键不存在时初始为 0 再 +1
    decr key数字值 -1(原子)
    incrby key 步长数字值 + 指定步长
    decrby key 步长数字值 - 指定步长
    mset k1 v1 k2 v2 ...一次设置多个键值对
    mget k1 k2 ...一次取多个值
    msetnx ...一次设置多个,任一 key 已存在则全部失败(原子)
    getrange key 起始 结束取子串(前包后包,索引从 0)
    setrange key 起始 值从指定位置覆写

    3、操作演示

    127.0.0.1:6379> set name tom
    OK
    127.0.0.1:6379> get name
    "tom"
    
    # 计数器
    127.0.0.1:6379> set page:view:100 0
    OK
    127.0.0.1:6379> incr page:view:100
    (integer) 1
    127.0.0.1:6379> incrby page:view:100 10
    (integer) 11
    127.0.0.1:6379> get page:view:100
    "11"
    
    # NX:不存在才设置
    127.0.0.1:6379> set lock:order:001 1 nx
    OK
    127.0.0.1:6379> set lock:order:001 2 nx
    (nil)          # 已存在,设置失败
    
    # 带过期
    127.0.0.1:6379> set verify:code 888888 ex 60
    OK
    
    # 以新换旧
    127.0.0.1:6379> getset name jerry
    "tom"
    127.0.0.1:6379> get name
    "jerry"
    
    # 批量
    127.0.0.1:6379> mset a 1 b 2 c 3
    OK
    127.0.0.1:6379> mget a b c
    1) "1"
    2) "2"
    3) "3"
    

    4、典型应用场景

    场景命令组合说明
    验证码SET verify:手机号 码 EX 120带过期,2 分钟有效
    登录 TokenSET token:xxx <值> EX 7200分布式 Session 的替代
    计数器INCR 文章ID:view浏览量、点赞数、库存扣减(原子,无并发问题)
    限流/标记SETNX lock:key + 过期简单分布式锁(第 8 讲完善)
    分布式 ID/去重配合字符串存唯一 ID

    3、Hash 类型

    1、什么是 Hash

    Hash 是一个 field-value 的键值对集合,可当作 Java 的 Map<String, String>。

    Key = user:1001
            ├── name  -> tom
            ├── age   -> 20
            └── city  -> shenzhen
    
    • 一个 key 对应一个 Hash,Hash 里能存 2^32-1 个 field。
    • 非常适合存"对象":一个对象一个 key,对象的每个属性一个 field。

    2、常用命令

    命令功能
    hset key field value [field value...]设置一个或多个 field
    hget key field取指定 field 的值
    hgetall key取全部 field-value
    hdel key field [field...]删除指定 field
    hexists key field判断 field 是否存在(1/0)
    hlen key返回 field 数量
    hkeys key列出所有 field
    hvals key列出所有 value
    hincrby key field 增量对指定 field 的数字值做增量(原子)
    hsetnx key field valuefield 不存在才设置(返回 1/0)
    hstrlen key field返回 field 值的长度

    3、操作演示

    127.0.0.1:6379> hset user:1001 name tom age 20 city shenzhen
    (integer) 3
    
    127.0.0.1:6379> hget user:1001 name
    "tom"
    
    127.0.0.1:6379> hgetall user:1001
    1) "name"
    2) "tom"
    3) "age"
    4) "20"
    5) "city"
    6) "shenzhen"
    
    # 计数器放进 Hash
    127.0.0.1:6379> hincrby user:1001 login:count 1
    (integer) 1
    
    # 判断字段
    127.0.0.1:6379> hexists user:1001 city
    (integer) 1
    
    # 只取字段/只取值
    127.0.0.1:6379> hkeys user:1001
    1) "name"
    2) "age"
    3) "city"
    127.0.0.1:6379> hvals user:1001
    1) "tom"
    2) "20"
    3) "shenzhen"
    

    4、典型应用场景

    • 对象存储:用户信息、商品信息、购物车(cart:userID + 商品ID + 数量)。
    • 对象的部分字段更新:只更新某一个属性,不需要整体替换(String 存 JSON 做不到"只改一个字段")。
    • Hash 计数器:把多个计数器集中在一个 key 下,避免建太多 String key。

    4、String 存对象 vs Hash 存对象

    对比项String + JSONHash
    结构整个对象序列化成 JSON 一个串对象一个 key,属性多个 field
    取单字段需整串取出再反序列化HGET field 直接取
    改单字段需整串改(重写 JSON)HSET field 单独改
    灵活性弱(整体读写)强(字段级读写)
    适合简单、字段少、整体存取字段多、经常局部更新的对象

    建议:字段多且要局部改用 Hash;简单整体存取用 String+JSON。真实项目两者都常用。


    5、本讲小结

    • String 是万能基础类型:二进制安全,配合 INCR/EX 可做计数器、验证码、Token、锁。
    • Hash 是对象的最优载体:一个对象一个 key、属性多个 field,字段级读写。
    • 记住高频命令:String 的 set/get/incr/mset/setex,Hash 的 hset/hget/hgetall/hincrby。

    6、课堂练习

    1. 用 String 实现一个"商品详情缓存":set goods:1001 <一段JSON>,再 get。
    2. 用 String 做一个"网站 UV 计数器",连续 incr 5 次观察返回值。
    3. 用 Hash 存一个学生对象(id/name/age),用 hget 只取出 name。
    4. 对比:给同一个对象分别用 String+JSON 和 Hash 存储,试一下"只改年龄"两种方式的命令差异。

    7、本节验证

    • 会用 SET/GET、INCR/DECR 计数器、APPEND/STRLEN 操作 String ✅
    • 会用 SETNX(不存在才设置)、带过期、批量(MSET/MGET)命令 ✅
    • 会用 HSET/HGET/HEXISTS/HKEYS/HVALS 操作 Hash ✅
    • 理解 String 存对象 vs Hash 存对象的差异与选型 ✅
    end