vault backup: 2026-05-27 23:01:37
This commit is contained in:
@@ -43,6 +43,90 @@ Redis 提供五种基础数据类型,用一句话总结各自的核心价值
|
||||
|
||||
> 想深入了解? [[02-核心数据类型/02-5-SDS|SDS]] · [[02-核心数据类型/02-1-ziplist与listpack|ziplist 与 listpack]] · [[02-核心数据类型/02-2-skiplist|skiplist]] · [[02-核心数据类型/02-3-hashtable|hashtable]] · [[02-核心数据类型/02-4-quicklist|quicklist]]
|
||||
|
||||
### key → value 映射全景
|
||||
|
||||
> [!tip] 五种类型,同一个套路
|
||||
> 无论哪种类型,Redis 的 key 永远是**一个字符串**(底层 SDS)。区别只在于 **value 的内部组织方式**。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
K["Redis Key 空间, 永远是 SDS"] --> V1["String: 一坨不可分割的值"]
|
||||
K --> V2["Hash: 多个 field-value 对"]
|
||||
K --> V3["List: 有序可重复序列"]
|
||||
K --> V4["Set: 无序不重复集合"]
|
||||
K --> V5["ZSet: member-score 对, 按 score 排序"]
|
||||
classDef key fill:#e1f5fe,stroke:#2196f3
|
||||
classDef val fill:#fff3e0,stroke:#ff9800
|
||||
class K key
|
||||
class V1,V2,V3,V4,V5 val
|
||||
```
|
||||
|
||||
每个类型的 value 具体长什么样——用实际业务数据来感受:
|
||||
|
||||
**String**:value 就是一个原子值,Redis 不关心里面是 JSON 还是纯文本。
|
||||
|
||||
```
|
||||
SET "session:abc123" "eyJhbGciOi..."
|
||||
┌──────────────────┐ ┌──────────────────────┐
|
||||
│ key │ │ value │
|
||||
│ "session:abc123" │ ──→ │ "eyJhbGciOi..." │
|
||||
│ │ │ 就是一个字符串,没了 │
|
||||
└──────────────────┘ └──────────────────────┘
|
||||
```
|
||||
|
||||
**Hash**:value 是一张"小表格",field 活在 value 内部,不是 Redis key。
|
||||
|
||||
```
|
||||
HSET "user:1001" name "alice" age "25" email "a@x.com"
|
||||
┌──────────────────┐ ┌───────────────────────────┐
|
||||
│ key │ │ value │
|
||||
│ "user:1001" │ ──→ │ name → "alice" │
|
||||
│ │ │ age → "25" │
|
||||
│ │ │ email → "a@x.com" │
|
||||
│ │ │ field 不是 key,仅限 value 内│
|
||||
└──────────────────┘ └───────────────────────────┘
|
||||
```
|
||||
|
||||
**List**:value 是一条有序队列,元素没有名字,只有位置。
|
||||
|
||||
```
|
||||
LPUSH "unread:1001" "notif:501" "notif:500" "notif:499"
|
||||
┌──────────────────┐ ┌─────────────────────────────────┐
|
||||
│ key │ │ value │
|
||||
│ "unread:1001" │ ──→ │ [0]notif:499 [1]notif:500 [2]... │
|
||||
│ │ │ ← 旧 新 → │
|
||||
│ │ │ 元素可以重复,有顺序 │
|
||||
└──────────────────┘ └─────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Set**:value 是一个不重复的袋子,没有顺序、没有分数。
|
||||
|
||||
```
|
||||
SADD "online:chat42" "user:1001" "user:2002" "user:3003"
|
||||
┌──────────────────┐ ┌──────────────────────────────┐
|
||||
│ key │ │ value │
|
||||
│ "online:chat42" │ ──→ │ { user:1001, user:2002, │
|
||||
│ │ │ user:3003 } │
|
||||
│ │ │ 去重无序,SADD 重复元素只保留一份 │
|
||||
└──────────────────┘ └──────────────────────────────┘
|
||||
```
|
||||
|
||||
**ZSet**:value 是一组 (member, score) 对,member 唯一、score 可重复。
|
||||
|
||||
```
|
||||
ZADD "leaderboard" 100 "alice" 200 "bob" 150 "carol"
|
||||
┌──────────────────┐ ┌──────────────────────────────┐
|
||||
│ key │ │ value │
|
||||
│ "leaderboard" │ ──→ │ bob → 200 ← 最高 │
|
||||
│ │ │ carol → 150 │
|
||||
│ │ │ alice → 100 ← 最低 │
|
||||
│ │ │ 按 score 排序,member 不可重复 │
|
||||
└──────────────────┘ └──────────────────────────────┘
|
||||
```
|
||||
|
||||
> [!question] Hash 的 field 和 ZSet 的 member 都"像 key",它们到底是不是 key?
|
||||
> **都不是。** 它们只存在于所属 key 的 value 内部。`HGET user:1001 name` 必须带上 key `user:1001` 才能访问——你不能用 `name` 全局查找。同理,ZSet 的 `member` 也不能脱离 `leaderboard` 独立存在。它们的作用域**仅限于各自 key 的 value 内部**。
|
||||
|
||||
我们先从最简单的 String 开始,逐个击破。
|
||||
|
||||
## 一、String(字符串)
|
||||
@@ -318,6 +402,21 @@ skiplist 天然有序,擅长范围查询("给我分数在 100~200 之间的
|
||||
> [!warning] ZSet 性能陷阱
|
||||
> 不要往同一个 ZSet 里塞超过百万级别的元素——skiplist 虽然 O(log N),但百万级的维护成本不小。可以按分片拆成多个 ZSet。
|
||||
|
||||
## 同一业务场景:五种类型怎么选?
|
||||
|
||||
假设你在做一个"用户主页",需要缓存以下信息:
|
||||
|
||||
| 信息 | 最佳类型 | key 设计 | value 存什么 |
|
||||
|------|---------|---------|-------------|
|
||||
| 用户 Token | **String** | `"token:uid1001"` | `"eyJhbG..."` (一个字符串) |
|
||||
| 用户资料 | **Hash** | `"user:1001"` | `{name, age, bio...}` (多个字段,可部分更新) |
|
||||
| 最近浏览记录 | **List** | `"browsed:1001"` | `["商品A","商品B","商品C"]` (有序可重复) |
|
||||
| 用户标签 | **Set** | `"tags:1001"` | `{"Go","Redis","后端"}` (去重无序) |
|
||||
| 全站积分排名 | **ZSet** | `"rank:global"` | `{uid1001:5200, uid2002:4800...}` (按分数排序) |
|
||||
|
||||
> [!summary] 一句话记忆
|
||||
> **key 是门牌号,value 是房间里的东西。** String 放一坨、Hash 放一张表、List 放一条队列、Set 放一个袋子、ZSet 放一个排行榜。
|
||||
|
||||
## 快速对照表
|
||||
|
||||
| 数据类型 | 编码 | 最佳场景 | 时间复杂度 |
|
||||
|
||||
Reference in New Issue
Block a user