第四篇:Redis 的 Key-Value 模型到底是什么?Key 应该怎么设计?

发布时间:2026/8/3 6:04:40

第四篇:Redis 的 Key-Value 模型到底是什么?Key 应该怎么设计? 前面三篇我们已经把 Redis 的运行模型串了起来Spring Boot 业务代码 ↓ StringRedisTemplate ↓ Lettuce 等 Redis 客户端 ↓ TCP Redis Server ↓ Redis 管理的内存数据我们也知道执行stringRedisTemplate.opsForValue() .set(user:name, 张三);本质上是 Java 客户端向 Redis Server 发送了一条命令SET user:name 张三Redis 收到命令后会在自己管理的内存中保存一条数据user:name → 张三但理解到这里之后还会出现一系列问题Redis 的 Key 到底是什么 Value 是不是只能保存字符串 为什么 Redis Key 经常使用冒号分隔 多个项目共用一个 Redis 时怎么避免 Key 冲突 Key 是越详细越好还是越短越好 Redis 能不能像 MySQL 一样通过条件查询 Key这些问题看起来只是命名细节实际上会直接影响数据是否容易管理 不同业务是否会冲突 缓存是否容易清理 线上问题是否容易排查 Redis 内存是否被浪费 后续系统是否容易扩展这一篇正式进入 Redis 的数据设计阶段重点讲清楚Redis 的 Key-Value 模型是什么以及真实项目中应该怎样设计 Key。一、Redis 最基础的数据模型Redis 最基础的数据模型可以表示为Key → Value例如user:name → 张三其中user:name → Key 张三 → Value可以暂时把它类比成 Java 中的 MapMapString, String map new HashMap(); map.put(user:name, 张三);读取String name map.get(user:name);Redis 中对应SET user:name 张三 GET user:name两者在使用形式上比较接近Java Map Key → Value Redis Key → Value但 Redis 不是当前 Java 进程中的普通 Map。区别在于Java Map → 数据位于当前 JVM 进程 Redis → 数据位于独立的 Redis Server 进程Java 访问 Redis 时需要通过 Redis 客户端和网络通信。二、Redis 中的 Key 可以理解成什么可以把 Redis Key 理解成一条数据的唯一名称。例如user:1001:name表示用户 1001 的姓名再例如article:2001:view表示文章 2001 的阅读量Redis 不会主动理解这些 Key 的业务含义。对 Redis 来说user:1001:name article:2001:view verify:code:13800000000都只是不同的 Key。冒号、单词和数字的业务含义都是开发者自己设计的。Redis 只负责根据完整 Key 查找 Value例如GET user:1001:nameRedis 会查找完整名称为user:1001:name的 Key。它不会主动分析user 是用户业务 1001 是用户 ID name 是字段名称这些分层只是我们为了方便管理而建立的命名规范。三、Redis Key 必须唯一吗在同一个 Redis 逻辑数据库中Key 是唯一的。例如第一次执行SET user:name 张三Redis 中的数据是user:name → 张三再次执行SET user:name 李四原来的值会被覆盖执行前 user:name → 张三执行后 user:name → 李四因为 Redis 不会同时保存两个完全相同的 Key。可以类比 Java Mapmap.put(user:name, 张三); map.put(user:name, 李四);最终map.get(user:name);得到的是李四所以同一个 Redis 数据库中一个完整 Key 只能对应一条 Redis 数据。如果业务 Key 设计不合理就可能出现数据覆盖。四、Redis 的 Value 只能是字符串吗不是。Redis 经常被称为 Key-Value 数据库但这里的 Value 并不只是一段普通字符串。Redis 常见的核心数据类型包括String Hash List Set ZSet例如Keyuser:1001对应的 Value 可以是 String 类型user:1001 → {id:1001,name:张三}也可以是 Hash 类型user:1001 ├── id → 1001 ├── name → 张三 └── phone → 13800000000再例如article:rank对应的 Value 可以是 ZSet用于保存排行榜文章 A → 100 分 文章 B → 80 分 文章 C → 120 分所以更准确的模型是一个 Key → 对应一种 Redis 数据类型的 Value例如user:1001:name → String user:1001 → Hash task:queue → List article:liked:1001 → Set article:rank → ZSet同一个 Key 在同一时间只能对应一种数据类型。五、一个 Key 不能同时是两种数据类型假设执行SET user:1001 张三此时user:1001 → String 类型如果随后把它当成 Hash 操作HSET user:1001 age 30Redis 会返回类型错误。因为user:1001已经是 String不能同时又作为 Hash 使用。这类错误通常会看到类似提示WRONGTYPE Operation against a key holding the wrong kind of value这说明 Redis 的 Key 不只是对应一个值还对应一个确定的数据类型。可以使用TYPE user:1001查看 Key 的数据类型。如果返回string表示它是 String。如果返回hash表示它是 Hash。因此Key 命名时最好能够让人看出它大致保存什么数据。六、Redis 为什么常用冒号分隔 Key实际项目中经常会看到这样的 Keyuser:info:1001 login:token:abc123 verify:code:13800000000 article:view:2001冒号在 Redis 中并没有特殊的层级语法。下面两个 Key 对 Redis 来说没有本质区别user:info:1001user_info_1001它们都只是一段完整字符串。之所以通常使用冒号是因为冒号能够让 Key 形成清晰的业务层次。例如ark:user:info:1001可以拆解为ark → 项目名称 user → 业务模块 info → 数据类型或业务用途 1001 → 唯一标识这种命名方式便于开发者阅读、排查和统一管理。因此冒号是一种约定俗成的命名分隔符而不是 Redis 的特殊语法。七、推荐的 Key 基本结构真实项目中可以采用下面的基本结构项目名:业务模块:数据用途:唯一标识例如ark:user:info:1001其中ark → ark-backend 项目 user → 用户模块 info → 用户信息 1001 → 用户 ID再例如验证码ark:verify:code:13800000000可以拆成ark → 项目名称 verify → 验证业务 code → 验证码 13800000000 → 手机号登录 Tokenark:login:token:abc123文章访问量ark:article:view:2001接口限流ark:limit:user:1001防重复提交ark:submit:order:user:1001这种结构的核心目的不是追求格式漂亮而是保证看见 Key 就知道属于哪个项目 看见 Key 就知道属于哪个业务 看见 Key 就知道保存什么数据 看见 Key 就知道对应哪个对象八、为什么建议加项目名前缀假设一台 Redis 被三个项目共同使用档案项目 电梯项目 商城项目如果三个项目都使用user:1001就可能发生冲突。例如档案项目写入SET user:1001 张三商城项目又写入SET user:1001 李四最终档案项目原来的数据会被覆盖。如果增加项目前缀archive:user:1001 lift:user:1001 mall:user:1001它们就是三个不同的 Key。因此共用 Redis 时通常应该使用项目简称:业务名称:唯一标识例如你的项目可以使用ark:user:info:1001 ark:login:token:abc123 ark:verify:code:13800000000这样可以减少不同项目之间的数据污染。九、Redis 有多个数据库为什么还要加项目前缀Redis 默认可以提供多个逻辑数据库。有些环境中可能会看到db0 db1 db2 ...可以使用SELECT 1切换到数据库 1。看起来似乎可以这样隔离项目 A 使用 db0 项目 B 使用 db1 项目 C 使用 db2但生产环境中通常不建议完全依赖逻辑数据库实现项目隔离。原因是它们仍然属于同一个 Redis 实例 同一个 Redis 进程 同一份服务器资源例如某个项目大量写入数据占满 Redis 内存其他逻辑数据库也会受到影响。另外Redis Cluster 模式下通常只使用数据库 0不支持像单机 Redis 一样自由切换多个逻辑数据库。因此更通用的做法是重要项目使用独立 Redis 实例 或者至少使用清晰的 Key 前缀项目名前缀仍然非常重要。十、用户相关 Key 应该怎么设计假设需要缓存用户 1001 的基本信息。可以设计为ark:user:info:1001Value 可以保存用户 JSON{ id: 1001, name: 张三, phone: 13800000000 }Redis 命令SET ark:user:info:1001 {\id\:1001,\name\:\张三\}Spring Boot 中可以写String key ark:user:info: userId; stringRedisTemplate.opsForValue() .set(key, userJson);如果缓存用户地址ark:user:address:1001如果缓存用户权限ark:user:permission:1001如果记录用户登录失败次数ark:user:login-fail:1001同一个用户可以有多个不同用途的 Keyark:user:info:1001 ark:user:address:1001 ark:user:permission:1001 ark:user:login-fail:1001关键是每个 Key 的用途必须清晰。十一、Token 相关 Key 应该怎么设计假设用户登录后生成 Tokenabc123一种设计方式是ark:login:token:abc123 → userId 1001Redis 命令SET ark:login:token:abc123 1001 EX 7200表示Tokenabc123 对应用户1001 有效期7200 秒Spring Boot 中String key ark:login:token: token; stringRedisTemplate.opsForValue() .set( key, String.valueOf(userId), 2, TimeUnit.HOURS );验证 Token 时String userId stringRedisTemplate .opsForValue() .get(ark:login:token: token);如果返回null可能表示Token 不存在 Token 已经过期 Token 已经被服务端删除也可以反向按照用户设计ark:login:user:1001 → abc123这种设计更方便实现一个用户只允许一个 Token 新设备登录时覆盖旧 Token 按用户 ID 强制下线Key 的设计应该根据查询方向决定。十二、验证码 Key 应该怎么设计短信验证码通常以手机号作为唯一标识ark:verify:code:13800000000写入SET ark:verify:code:13800000000 9527 EX 300表示手机号13800000000 验证码9527 有效期300 秒Spring Boot 中String key ark:verify:code: phone; stringRedisTemplate.opsForValue() .set( key, code, 5, TimeUnit.MINUTES );校验String redisCode stringRedisTemplate .opsForValue() .get(key);验证码 Key 设计需要能够回答这是什么业务的验证码 这是哪个用户或手机号的验证码 验证码有效期是多少如果同一个系统有多种验证码还可以继续细分ark:verify:login:13800000000 ark:verify:register:13800000000 ark:verify:reset-password:13800000000否则不同业务可能相互覆盖。例如登录验证码和修改密码验证码都使用ark:verify:code:13800000000后发送的验证码会覆盖前一个。因此应根据业务场景增加类型项目名:验证码业务:场景:手机号十三、文章访问量 Key 应该怎么设计记录文章 2001 的访问量可以设计为ark:article:view:2001初始化SET ark:article:view:2001 0每访问一次INCR ark:article:view:2001查看GET ark:article:view:2001这里的 Key 结构是ark → 项目 article → 文章模块 view → 阅读量 2001 → 文章 ID如果还要记录点赞量ark:article:like:2001评论数ark:article:comment:2001收藏量ark:article:favorite:2001这样的 Key 结构比较清晰。十四、Key 中应该使用用户 ID 还是手机号假设要保存用户缓存可以选择ark:user:info:1001也可以选择ark:user:info:13800000000通常更推荐使用稳定、唯一且较短的内部 IDark:user:info:1001原因包括1. 用户 ID 通常更加稳定手机号可能会更换。用户 ID 通常不会变化。2. 避免敏感信息直接出现在 Key 中手机号、身份证号、邮箱等信息直接出现在 Redis Key 中可能增加日志和运维排查过程中的隐私暴露风险。3. 用户 ID 通常更短短 Key 可以减少一定内存占用。因此正式业务数据通常优先使用内部唯一 ID但验证码场景天然需要通过手机号查询此时手机号作为 Key 的一部分是合理的。Key 设计需要根据实际查询方式决定。十五、Key 是越长越好吗不是。一个极其详细的 Key 可能是ark-backend-project:user-module:user-information-cache:user-id:1001它确实非常清晰但也过于冗长。Redis 中通常会存在大量 Key。如果每个 Key 都很长就会增加内存占用。假设有一百万个 Key每个 Key 多出几十个字符整体内存差异就会非常明显。因此Key 设计需要在可读性 和 空间占用之间取得平衡。例如ark:user:info:1001通常已经足够表达业务含义。没有必要写成ark-backend-system:user-management-module:user-basic-information-cache:1001推荐原则是Key 应该清晰但不要为了描述完整而无限增长。十六、Key 是越短越好吗也不是。例如把用户缓存设计成u:1001确实很短。但团队成员看到它时可能无法确定u 是 user 还是 upload 保存的是用户信息还是用户状态 这是哪个项目的用户再例如t:a1几乎无法通过 Key 判断业务含义。这种 Key 虽然节省少量空间但会增加维护成本。线上排查时运维或开发看到u:1001 t:a1 v:2001很难判断它们分别是什么。因此Key 太长 → 浪费内存书写复杂 Key 太短 → 缺少业务含义难以维护更合理的是使用稳定、简洁、可读的缩写ark:user:info:1001 ark:login:token:abc123 ark:article:view:2001十七、Key 命名应该统一大小写Redis Key 区分大小写。下面是三个不同的 Keyuser:1001 User:1001 USER:1001Redis 不会把它们当成同一个 Key。例如SET user:1001 张三 SET User:1001 李四此时 Redis 中会存在两条数据。因此团队必须统一大小写规范。通常推荐全部使用小写ark:user:info:1001不要混用Ark:User:Info:1001 ARK:user:INFO:1001全小写的优势是风格统一 减少输入错误 避免大小写冲突 便于团队协作十八、Key 中应该使用空格吗虽然 Redis 的 Key 可以包含很多字符但不建议在业务 Key 中使用空格。例如ark user info 1001在命令行中需要额外处理SET ark user info 1001 张三这会增加命令输入难度 日志阅读难度 脚本处理难度 排查问题的复杂度因此一般使用冒号 短横线 下划线其中最常见的是冒号ark:user:info:1001业务单词内部可以使用短横线ark:user:reset-password:1001核心是保持团队统一。十九、Key 中能不能使用中文Redis 的 Key 本质上可以保存字节数据因此技术上可以使用中文。例如SET 用户:1001:姓名 张三但生产项目中一般不建议大量使用中文 Key。原因包括不同工具显示可能不一致 脚本处理不方便 跨语言协作不方便 编码问题更难排查 命令行输入效率较低更推荐ark:user:name:1001Value 中保存中文通常没有问题SET ark:user:name:1001 张三也就是Key → 建议使用规范英文和数字 Value → 根据业务正常保存中文内容二十、Key 能不能像数据库字段一样模糊查询Redis 的主要使用方式是通过完整 Key 查询。例如GET ark:user:info:1001Redis 可以快速找到对应数据。但是有时我们可能想查询所有 ark:user 开头的 KeyRedis 提供了相关命令例如KEYS ark:user:*它可能返回ark:user:info:1001 ark:user:info:1002 ark:user:address:1001 ark:user:permission:1001但生产环境中要非常谨慎使用KEYS。二十一、为什么生产环境不建议随便使用 KEYSKEYS会扫描符合模式的所有 Key。例如KEYS *表示查找当前数据库中的所有 Key。如果 Redis 中只有几十个 Key问题可能不明显。但如果 Redis 中有几十万 几百万 甚至更多 Key执行KEYS *可能占用 Redis 较长时间。Redis 在处理这个命令期间其他请求可能受到影响。因此生产环境中通常不建议随意执行KEYS *或者KEYS ark:user:*尤其是在数据量较大时。Redis 不是为了让我们像数据库一样频繁模糊搜索 Key 而设计的。正确思路应该是在写入数据之前就设计好明确、可直接计算出来的 Key。例如通过用户 ID 得到String key ark:user:info: userId;然后直接查询stringRedisTemplate.opsForValue().get(key);二十二、需要遍历 Key 时使用什么如果确实需要逐步扫描 Key可以使用SCAN例如SCAN 0 MATCH ark:user:* COUNT 100SCAN会以游标方式分批返回结果而不是一次性扫描完所有 Key。可以简单理解为KEYS → 一次性找完 SCAN → 分批逐步查找SCAN对线上环境相对友好但也不代表可以毫无成本地频繁使用。应用业务代码中最好仍然通过明确的 Key 直接访问。如果某个业务经常需要查询所有用户缓存 查询某类全部 Key 按照多个条件筛选可能说明数据结构设计不合理或者这部分需求更适合数据库、Set、ZSet 等结构。二十三、如何检查一个 Key 是否存在可以使用EXISTS ark:user:info:1001如果 Key 存在返回1如果不存在返回0Spring Boot 中可以写Boolean exists stringRedisTemplate .hasKey(ark:user:info:1001);但实际业务中不要为了查询一个值先执行EXISTS再执行GET例如下面这种写法可能会产生两次 Redis 请求if (Boolean.TRUE.equals( stringRedisTemplate.hasKey(key) )) { return stringRedisTemplate .opsForValue() .get(key); }很多情况下可以直接String value stringRedisTemplate .opsForValue() .get(key); if (value null) { // Key 不存在或已经过期 }这样只需要一次访问。EXISTS适合确实只关心 Key 是否存在的场景。二十四、如何查看 Key 的数据类型可以使用TYPE ark:user:info:1001可能返回string或者hash list set zset none如果返回none表示 Key 不存在。Spring Boot 中也可以获取类型但在日常业务中一般不会频繁动态判断。更合理的是在 Key 设计阶段就确定每类 Key 对应的数据类型。例如统一约定ark:user:info:{userId} → String保存用户 JSON ark:user:profile:{userId} → Hash保存用户字段 ark:article:liked:{articleId} → Set保存点赞用户 ID ark:article:rank → ZSet保存文章排行榜不要让同一个业务 Key 在不同代码中被当成不同类型使用。二十五、Key 是否应该设置过期时间不是所有 Key 都必须过期但大多数缓存数据都应该考虑过期时间。例如用户信息缓存ark:user:info:1001可以设置 30 分钟过期SET ark:user:info:1001 {...} EX 1800验证码ark:verify:login:13800000000设置 5 分钟过期SET ark:verify:login:13800000000 9527 EX 300Tokenark:login:token:abc123设置 2 小时过期SET ark:login:token:abc123 1001 EX 7200如果缓存数据永不过期就可能出现旧数据长期存在 无用 Key 越来越多 Redis 内存持续增长 数据库数据已经更新但缓存仍然陈旧因此设计 Key 时不仅要考虑名称还应该同时考虑Value 类型 过期时间 更新方式 删除方式 数据来源二十六、Key 删除后会发生什么删除 KeyDEL ark:user:info:1001之后GET ark:user:info:1001会返回空结果。在缓存场景中删除 Key 并不代表正式用户数据被删除。例如MySQL → 仍然保存用户 1001 Redis → 用户缓存被删除下一次请求可能会先查询 Redis ↓ Redis 没有 ↓ 查询 MySQL ↓ 重新写入 Redis因此删除缓存 Key 的含义通常是让当前缓存副本失效下一次重新从正式数据源加载。这和删除 MySQL 中的正式数据完全不同。二十七、Key 设计必须考虑如何删除假设用户退出登录需要删除 Tokenark:login:token:abc123这个 Key 很容易计算String key ark:login:token: token;然后删除stringRedisTemplate.delete(key);但如果 Key 设计混乱例如abc123-token-login-user-1001-ark虽然也能工作但代码维护和问题排查会更加困难。好的 Key 设计应该同时支持容易生成 容易查询 容易删除 容易判断用途 容易统一设置过期时间不能只考虑写入时是否方便。二十八、不要把所有参数都塞进 Key假设有一个商品查询接口分类手机 品牌华为 价格区间30005000 排序销量降序 页码1 每页20如果直接把所有参数拼进 Keymall:product:list:category-phone:brand-huawei: price-3000-5000:sort-sales-desc:page-1:size-20Key 会变得非常长而且参数顺序、空值处理、字符编码都可能产生问题。复杂查询缓存通常需要规范化请求参数 固定参数顺序 对参数生成摘要 控制缓存维度 防止产生海量不同 Key例如可以将规范化参数计算哈希mall:product:list:7f83a2...但这种做法会降低可读性需要配合日志和文档。目前学习阶段只需要知道简单实体缓存可以直接使用业务 ID复杂查询缓存不能无脑拼接所有参数。二十九、避免缓存 Key 数量无限增长假设搜索接口按照搜索词缓存ark:search:keyword:redis ark:search:keyword:mysql ark:search:keyword:spring如果任何用户输入都生成一个新 Key可能出现用户输入一次 → 生成一个新 Key 不同搜索词越来越多 → Redis Key 数量持续增长这种问题称为缓存空间失控的一种表现。因此 Key 设计还要考虑业务可能产生多少个 Key Key 是否会自动过期 是否存在用户恶意输入 是否有最大数量限制 是否真的值得缓存Redis Key 设计不是简单的字符串命名而是一种数据规模设计。三十、推荐建立统一的 Key 常量Spring Boot 项目中不建议在业务代码里到处手写ark:user:info:例如String key ark:user:info: userId;另一个类又写String key ark:user:information: userId;这可能导致同一个业务产生两套 Key。可以建立统一常量public final class RedisKeyConstants { private RedisKeyConstants() { } public static final String PROJECT_PREFIX ark; public static final String USER_INFO PROJECT_PREFIX :user:info:; public static final String LOGIN_TOKEN PROJECT_PREFIX :login:token:; public static final String VERIFY_LOGIN PROJECT_PREFIX :verify:login:; public static final String ARTICLE_VIEW PROJECT_PREFIX :article:view:; }使用String key RedisKeyConstants.USER_INFO userId;这样可以统一维护。三十一、进一步封装 Key 构建方法如果 Key 结构较多可以进一步封装public final class RedisKeys { private static final String PROJECT ark; private RedisKeys() { } public static String userInfo(Long userId) { return PROJECT :user:info: userId; } public static String loginToken(String token) { return PROJECT :login:token: token; } public static String loginVerifyCode(String phone) { return PROJECT :verify:login: phone; } public static String articleView(Long articleId) { return PROJECT :article:view: articleId; } }使用String key RedisKeys.userInfo(1001L);得到ark:user:info:1001这种方式的优势是统一命名 减少字符串拼写错误 方便批量调整前缀 业务含义更加清晰 更容易编写测试三十二、是否要把环境名称加进 Key实际项目可能有多个环境开发环境 测试环境 预发布环境 生产环境如果它们错误地共用同一个 Redis就可能互相覆盖数据。可以在 Key 中增加环境前缀dev:ark:user:info:1001 test:ark:user:info:1001 prod:ark:user:info:1001但更合理的部署方式通常是不同环境使用不同 Redis 实例因为即使增加 Key 前缀它们仍然共用同一份 Redis 内存 同一套资源 同一套故障范围环境前缀可以作为额外保护但不能代替环境隔离。三十三、一个实用的 Key 设计规范对于当前阶段可以先使用下面这套规范。1. 全部小写ark:user:info:1001避免ARK:User:Info:10012. 使用冒号分层项目:模块:用途:唯一标识3. 使用稳定唯一标识优先用户 ID 订单 ID 文章 ID 设备 ID4. 不使用无意义缩写推荐ark:user:info:1001谨慎使用a:u:i:10015. 不包含不必要的敏感信息尽量避免直接放入身份证号 完整手机号 密码 密钥 Token 明文日志Token 作为 Key 的组成部分有时难以避免但日志中要注意脱敏。6. 明确数据类型例如提前约定ark:user:info:{id} → String JSON7. 明确过期时间例如用户缓存30分钟 验证码5分钟 Token2小时 防重复提交10秒8. Key 必须可以直接计算尽量避免业务代码依赖模糊扫描才能找到数据。三十四、为 ark-backend 设计一组 Key结合你的后端项目可以先设计下面这组 Key。用户信息缓存ark:user:info:{userId}例如ark:user:info:1001用户地址缓存ark:user:address:{userId}登录 Tokenark:login:token:{token}用户当前 Tokenark:login:user:{userId}登录验证码ark:verify:login:{phone}注册验证码ark:verify:register:{phone}登录失败次数ark:login:fail:{account}防重复提交ark:submit:{business}:{userId}例如ark:submit:create-order:1001接口限流ark:limit:{api}:{userId}例如ark:limit:send-code:1001文章访问量ark:article:view:{articleId}通过这一组 Key可以看到统一结构ark → 项目名称 第二段 → 业务模块 第三段 → 数据用途 最后一段 → 唯一标识三十五、Redis Key 设计不是数据库表设计MySQL 中可能有user 表字段包括id name phone status create_timeRedis 中不一定要为每个字段单独设计 Keyark:user:name:1001 ark:user:phone:1001 ark:user:status:1001 ark:user:create-time:1001这样会产生大量 Key并增加多次网络请求。更常见的是把用户作为一个整体缓存ark:user:info:1001 → 用户 JSON或者使用 Hashark:user:info:1001 ├── name → 张三 ├── phone → 13800000000 └── status → 1因此 Redis Key 的粒度需要根据数据读取方式 字段更新频率 数据大小 网络请求次数 缓存失效方式综合判断。不要机械地把 MySQL 每一行、每一列都转换成 Redis Key。三十六、Redis 适合通过 Key 精准访问MySQL 的典型访问方式是SELECT * FROM user WHERE status 1 AND create_time 2026-01-01;Redis 更典型的访问方式是GET ark:user:info:1001也就是已经知道唯一 Key → 直接获取数据如果业务需求是按多个条件筛选 关联多张表 动态排序 复杂分页 聚合统计通常更适合 MySQL、Elasticsearch 等系统。Redis 更擅长根据明确 Key 获取数据 根据明确成员操作集合 按照分数查询排行榜 进行计数和临时状态管理所以 Redis Key 的核心设计目标是让业务代码能够根据已知参数直接计算出目标 Key。三十七、本篇动手实践打开redis-cli执行下面的命令。1. 保存用户信息SET ark:user:info:1001 {\id\:1001,\name\:\张三\}读取GET ark:user:info:1001检查是否存在EXISTS ark:user:info:1001查看类型TYPE ark:user:info:10012. 保存验证码SET ark:verify:login:13800000000 9527 EX 300读取GET ark:verify:login:13800000000查看剩余时间TTL ark:verify:login:138000000003. 记录访问量SET ark:article:view:2001 0增加INCR ark:article:view:2001读取GET ark:article:view:20014. 查看当前 Key学习环境中可以执行KEYS ark:*但需要记住生产环境不要随意使用KEYS *。三十八、本篇总结这一篇正式介绍了 Redis 的 Key-Value 数据模型。Redis 中的每条数据都通过唯一 Key 标识Key → Value但 Value 不只可以是普通字符串还可以是String Hash List Set ZSet同一个 Key 在同一时间只能对应一种 Redis 数据类型。Redis Key 中常见的冒号并不是特殊语法而是一种方便管理的命名约定。推荐的基础结构是项目名:业务模块:数据用途:唯一标识例如ark:user:info:1001 ark:login:token:abc123 ark:verify:login:13800000000 ark:article:view:2001设计 Key 时需要同时考虑唯一性 可读性 长度 大小写 数据类型 过期时间 查询方式 删除方式 数据规模Key 不能过长也不能为了节省几个字符而失去业务含义。Redis 最擅长通过完整 Key 精准访问数据而不是像 MySQL 一样频繁进行复杂条件查询。最终可以用一句话总结Redis Key 是数据在 Redis 中的唯一业务地址。好的 Key 设计应该让程序能够直接计算、准确查询、方便删除并让开发者看到 Key 就能判断它属于哪个项目、哪个业务以及哪一条数据。下一篇预告下一篇继续学习 Redis 最常用的数据类型《Redis String 类型和过期时间 TTL验证码为什么会自动失效》下一篇会重点讲清楚Redis String 到底能保存什么 SET 和 GET 的常见用法 SETEX、EX、PX 分别是什么 EXPIRE 如何设置过期时间 TTL 的返回值为什么有 -1 和 -2 验证码到期后是谁删除的 Redis 如何判断一个 Key 已经过期 INCR 为什么可以安全计数 Token、验证码和缓存应该如何设置有效期下一篇开始我们会使用 String 完成 Redis 中最常见的几类业务操作。

相关新闻