[toc]
| 单词 | 词性 | 音标 | 含义 |
|---|---|---|---|
| binary | adj. | /ˈbaɪnəri/ | 二进制的(Redis String 二进制安全,可存图片、序列化对象等) |
| safe | adj. | /seɪf/ | 安全的(不会对存入的二进制数据做重新编码) |
| incr | v. | /ɪnˈkr/ | 递增(INCR key 对数字值原子 +1,计数器核心命令) |
| decr | v. | /dɪˈkr/ | 递减(DECR key 原子 -1) |
| append | v. | /əˈpend/ | 追加(APPEND key value 在原值末尾追加) |
| strlen | n. | /str len/ | 字符串长度(STRLEN key 返回值的长度) |
| field | n. | /fiːld/ | 字段(Hash 中的子键,类似 Map 的 key) |
| hash | n. | /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 分钟有效 |
| 登录 Token | SET 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 value | field 不存在才设置(返回 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 + JSON | Hash |
|---|---|---|
| 结构 | 整个对象序列化成 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、课堂练习
- 用 String 实现一个"商品详情缓存":
set goods:1001 <一段JSON>,再get。 - 用 String 做一个"网站 UV 计数器",连续
incr5 次观察返回值。 - 用 Hash 存一个学生对象(id/name/age),用
hget只取出 name。 - 对比:给同一个对象分别用 String+JSON 和 Hash 存储,试一下"只改年龄"两种方式的命令差异。
7、本节验证
- 会用 SET/GET、INCR/DECR 计数器、APPEND/STRLEN 操作 String ✅
- 会用 SETNX(不存在才设置)、带过期、批量(MSET/MGET)命令 ✅
- 会用 HSET/HGET/HEXISTS/HKEYS/HVALS 操作 Hash ✅
- 理解 String 存对象 vs Hash 存对象的差异与选型 ✅