青戈AI小栈
会员限时8折
Redis 精讲:从数据结构到缓存与并发实践

Redis 能解决什么:第一次保存和读取数据

3,952 字约 10 分钟读完48 次阅读更新于 2026/10/22

登录后收藏

阅读设置

字号
行距
代码

在后端开发中,Redis 经常与 MySQL 一起出现。商品详情缓存、验证码、接口限流、排行榜,都可能用到它。

本篇以商品名称为例,在浏览器中完成保存、读取、修改和删除,观察键与值怎样对应。使用在线编辑器即可练习,不需要先安装 Docker 或 Redis。

Redis 是一个主要在内存中处理数据的键值数据库。 MySQL 通常把业务数据组织成表和记录,Redis 则通过一个键找到对应的值。例如,给商品名称起一个唯一的键,写入后就可以用这个键取回名称。除了字符串,Redis 还支持集合等数据类型,后续可以用来保存收藏和排行榜。

Redis 独立运行,程序通过客户端向它发送命令,再取得执行结果。

打开网页,运行第一条命令

打开 OneCompiler Redis 在线编辑器。页面提供命令编辑区、Run 按钮和 Output 输出区;窄屏下可以通过 Code 与 Output 切换编辑和结果。

把 commands.redis 中已有的示例全部替换为:

bash
PING

点击 Run,在 Output 中应看到:

输出
PONG

PING 用于检查运行环境中的 Redis 能否响应。在线编辑器负责把命令交给运行环境,当前步骤不需要输入主机、端口或连接密码。

后面的每个命令块都对应一次完整运行,紧随其后的是预期输出。每次先替换编辑区的全部内容,再点击 Run。只复制命令,不复制输出。

本篇每个命令块都在同一次运行中先写入、再读取:需要什么数据,就在当前块前面写入什么数据。单独运行一条 GET,读不到上一次运行写入的值。

用一个键保存商品名称

把编辑区全部替换为以下两行,一次运行:

bash
SET catalog:product:1001:name "机械键盘"
GET catalog:product:1001:name

预期输出:

输出
OK
机械键盘

键(Key) 是数据的名称,值(Value) 是保存的内容。这里的键是 catalog:product:1001:name,值是 机械键盘。值统一用英文双引号包起来;值里带空格时(例如 USB 数据线),不加引号会被拆成多个参数,命令直接报错:SET catalog:product:1003:name USB 数据线 返回 ERR syntax error。

键中的冒号只是命名约定,不会创建文件夹或数据库表。这个名字依次表示商品目录、商品、编号 1001 和名称字段,便于辨认数据属于哪个业务。

本篇使用 String(字符串) 类型。SET 写入字符串,成功返回 OK;GET 按键取回字符串。因此两行输出分别对应写入和读取。编辑器按从上到下的顺序执行这些命令,后面的读取能看到前面的写入。GET 官方命令说明(英文)

flowchart LR
  C[编辑区里的命令] -->|SET / GET| R[Redis]
  R -->|返回值| O[Output 输出区]
  classDef client fill:#ddf4ff,stroke:#0969da,color:#1f2328
  classDef server fill:#dafbe1,stroke:#1a7f37,color:#1f2328
  classDef result fill:#fff8c5,stroke:#9a6700,color:#1f2328
  class C client
  class R server
  class O result

引号用来界定命令参数的边界,不是名称内容的一部分。OneCompiler 当前以简洁格式展示输出,字符串不带引号,整数也没有类型前缀。本篇输出以这个页面为准。

再写一次,会增加一条还是覆盖一条

先预测最后一次读取的结果,再替换编辑区并运行:

bash
SET catalog:product:1001:name "机械键盘"
GET catalog:product:1001:name
SET catalog:product:1001:name "无线键盘"
GET catalog:product:1001:name

预期输出:

输出
OK
机械键盘
OK
无线键盘

对同一个键再次执行 SET,会覆盖旧值,不会为这个键追加一条历史记录。第一条 GET 发生在修改前,最后一条发生在修改后,所以读到两个不同名称。保存另一件商品,需要另一个键,例如 catalog:product:1002:name。SET 官方命令说明(英文)

删除返回的是数量

替换为下面的完整命令块,再运行:

bash
SET catalog:product:1001:name "无线键盘"
DEL catalog:product:1001:name
DEL catalog:product:1001:name

预期输出:

输出
OK
1
0

DEL 返回实际删除的键数。第一次删除时键存在,删掉一个键,返回 1;第二次已经不存在,没有键可删,返回 0,而不是报错。这里的数字不是商品编号,也不代表成功或失败。DEL 官方命令说明(英文)

删除后读取,为什么看到空行

替换为下面的命令块:

bash
SET catalog:product:1001:name "无线键盘"
DEL catalog:product:1001:name
GET catalog:product:1001:name
PING

预期输出:

输出
OK
1

PONG

1 和 PONG 之间有一个空行,对应 GET 的回复:键已删除,Redis 返回空值,OneCompiler 把它显示为空行。最后加上 PING,是为了让这行空结果的位置更容易看清。

空值表示键不存在,并不是字符串 "nil" 或 "null"。交互式 redis-cli 会把这类结果显示为 (nil),而这里显示为空行;展示方式不同,含义相同。

Redis 与商品数据库怎样分工

后续项目使用 MySQL 保存商品记录,Redis 暂存适合复用的数据。缓存是保留一份可重新取得或计算的数据,让后续访问尽量复用这份结果。

在线编辑器的运行边界不等于 Redis 的连接边界:以后使用本机 Redis 时,只要服务中数据仍存在,不同客户端连接可以读取同一个键。

MySQL 中有商品,不代表 Redis 中也一定有;Redis 中某个商品键不存在,也不能直接认定商品不存在。接口后续会先查缓存,缺失时再查数据库。商品修改后怎样处理旧缓存,是另一个需要实现的步骤。

现在只是在验证 Redis 的读写,还没有连接商品数据库,也没有实现接口缓存。Redis 主要在内存中处理数据,但仍有网络、执行时间与容量等成本,不能因为接入 Redis 就认定接口一定更快。

命令出错时检查哪里

如果输出与预期不同,先看 Output 是否包含错误,再检查编辑区中是否保留了旧示例。一个命令占一行,值里有空格时用英文双引号包起来,冒号组成的键名中不要插入空格。也不要把教程里的预期输出一并粘贴进去。

如果只读到空行,检查当前命令块是否先写入同一个键,以及读取前是否执行了删除。键名中的商品编号也要一致。页面一直处于运行中或无法加载时,检查网络或稍后重试,不要把在线服务的问题当成命令返回空值。

本篇已经完成写入、读取、覆盖和删除:同一个键写入会覆盖,删除返回实际删除数量,读取不存在的键返回空值。下一篇为数据设置存活时间;本机安装与 Python 连接放到实际接入程序时完成。

练习

打开 OneCompiler Redis 在线编辑器,用一次完整运行完成下面的操作。全部命令写在同一个命令块中,不依赖前一次 Run 留下的数据。

  1. 为商品 2001 保存名称 USB 数据线,读取确认;再把名称改成 USB 快充数据线,再次读取。执行前预测第二次写入会覆盖还是追加,并用结果验证。
  2. 为商品 2002 保存名称 桌面支架。只删除商品 2001 的名称,分别读取两个商品的名称,再次删除商品 2001 的名称。
  3. 在最后加上 PING。按命令顺序解释每一条输出,包括商品 2001 删除后读取所产生的空行。

验收: 商品 2001 的两次读取依次得到 USB 数据线 与 USB 快充数据线;删除后读取为空;两次删除分别返回 1 和 0;商品 2002 仍返回 桌面支架;最后收到 PONG。同一个完整命令块重复运行,仍能得到上述结果。

查看提示

商品编号决定键名,名称中的空格需要英文双引号。更新沿用原键,另一件商品换一个键。删除返回的是这次实际删掉多少个键。

把写入、修改、删除和读取都放在当前命令块中,按顺序执行。空值在 OneCompiler 中显示为空行,后面保留另一条有输出的命令,方便确认它对应哪个操作。

查看参考答案

在 OneCompiler Redis 在线编辑器中,把 commands.redis 的全部内容替换为以下命令,再点击 Run。所有操作在同一次运行中完成。

bash
SET catalog:product:2001:name "USB 数据线"
GET catalog:product:2001:name
SET catalog:product:2001:name "USB 快充数据线"
GET catalog:product:2001:name
SET catalog:product:2002:name "桌面支架"
DEL catalog:product:2001:name
GET catalog:product:2001:name
GET catalog:product:2002:name
DEL catalog:product:2001:name
PING

预期输出:

输出
OK
USB 数据线
OK
USB 快充数据线
OK
1

桌面支架
0
PONG

前四条命令先写入、读取,再覆盖、读取。两次 SET 使用同一个键,后一次覆盖原名称,最后读到 USB 快充数据线,不产生名称历史。

第五条命令为商品 2002 保存名称,返回 OK。第六条命令删除商品 2001,键存在,因此返回 1。

第七条命令读取已删除的键,返回空值,在输出中表现为 1 后面的空行。第八条读取商品 2002,得到 桌面支架;两个商品使用不同的键,删除 2001 不影响 2002。

第九条再次删除商品 2001,没有键可删,返回 0。最后一条 PING 返回 PONG,证明这一条也执行到了。

直接再次点击 Run,完整命令块会重新写入所需数据,再覆盖和删除。它不需要前一次运行留下数据,因此结果可以复现。

有帮助
登录后提问 / 纠错

提问与反馈

仅你和管理员可见。我的反馈

设置你的昵称

在英雄榜和讨论中,使用你自己的名字。

2–12 个字符0 / 12