Redis 从 0 到 1(三):五大结构 20 个最常用命令,用 Go 各写一个真实用法(附速查表)

发布时间:2026/10/11 8:47:52

Redis 从 0 到 1(三):五大结构 20 个最常用命令,用 Go 各写一个真实用法(附速查表) 我不会起名字322· 后端 / 算法 / 数据库 技术栈 力扣 Hot100 Go 项目 Redis MySQL文章目录Redis 从 0 到 1三五大结构 20 个最常用命令用 Go 各写一个真实用法附速查表一、先纠正一个学习顺序二、Go 实操5 个场景 20 个命令场景 1String —— 缓存用户对象 接口访问计数场景 2Hash —— 购物车字段级增删改场景 3List —— 最新消息时间线场景 4Set —— 共同关注与标签场景 5ZSet —— 排行榜第 15 篇有完整的工程细节三、20 命令速查表收藏点 1四、容易踩的 3 个坑五、总结Redis 从 0 到 1三五大结构 20 个最常用命令用 Go 各写一个真实用法附速查表上一篇《Redis 从 0 到 1二Go 连 Redis 半夜总报 EOF连接池 5 参数与 redisx 封装》我们做出了全系列复用的 redisx 连接封装链接https://blog.csdn.net/2501_92769340/article/details/167399361 。本篇开始用连接干活五大结构的 20 个最常用命令每个都放进真实业务场景里用 Go 写一遍。一、先纠正一个学习顺序很多人学 Redis 命令的方式是把 String 的 30 个命令背一遍三个月后只记得 SET 和 GET。问题不在记忆力在于命令没有挂在场景上。面试官问购物车用什么结构能答上来的人才是真的会了。本篇的学习路径反着来先给 5 个真实场景再看每个场景为什么选这个结构、用哪几个命令。场景结构为什么选它缓存用户对象 / 计数器String最简单序列化整存整取INCR 原子计数商品详情 / 购物车Hash字段级读写改一个字段不用整取整个对象最新消息列表 / 简单队列List有序、两头进出LPUSHLRANGE 就是时间线共同关注 / 标签去重Set去重 交集并集是原生操作排行榜 / 延迟任务ZSet每个元素带分数按分数排序 O(logN)二、Go 实操5 个场景 20 个命令以下代码基于上一篇的 redisx 封装省略 main 函数框架每段都是可直接运行的核心逻辑完整代码见系列仓库。场景 1String —— 缓存用户对象 接口访问计数funcdemoString(ctx context.Context,rdb*redis.Client)error{// 1. SETEX缓存对象必须带 TTL第 11 篇讲为什么userJSON:{id:1001,name:zhangsan}iferr:rdb.SetEx(ctx,user:1001,userJSON,30*time.Minute).Err();err!nil{returnfmt.Errorf(缓存用户失败: %w,err)}// 2. GET 反序列化val,err:rdb.Get(ctx,user:1001).Result()iferrors.Is(err,redis.Nil){// key 不存在不是错误是缓存未命中fmt.Println(缓存未命中回源数据库)}elseiferr!nil{returnerr}fmt.Println(读到缓存:,val)// 3. SET NX只在不存在时写入第 13 篇分布式锁的基础ok,err:rdb.SetNX(ctx,user:1001:lock,1,10*time.Second).Result()fmt.Println(抢到锁:,ok,err)// 4. INCR原子计数接口限流、阅读量都靠它pv,err:rdb.Incr(ctx,article:42:pv).Result()fmt.Println(当前阅读量:,pv,err)returnerr}场景 2Hash —— 购物车字段级增删改funcdemoHash(ctx context.Context,rdb*redis.Client)error{key:cart:1001// 5. HSet加入购物车field商品ID, value数量iferr:rdb.HSet(ctx,key,sku_888,2,sku_999,1).Err();err!nil{returnerr}// 6. HIncrBy商品数量 1改字段不用读整个购物车iferr:rdb.HIncrBy(ctx,key,sku_888,1).Err();err!nil{returnerr}// 7. HGetAll结算时取整个购物车cart,err:rdb.HGetAll(ctx,key).Result()fmt.Println(购物车:,cart,err)// 8. HDel删除某个商品returnrdb.HDel(ctx,key,sku_999).Err()}场景 3List —— 最新消息时间线funcdemoList(ctx context.Context,rdb*redis.Client)error{key:timeline:1001// 9. LPush发一条新动态就推到头部rdb.LPush(ctx,key,msg_3,msg_2,msg_1)// 10. LTrim只保留最新 100 条防止无限膨胀bigkey 预防见第 22 篇rdb.LTrim(ctx,key,0,99)// 11. LRange拉第一页最新的 10 条msgs,err:rdb.LRange(ctx,key,0,9).Result()fmt.Println(时间线:,msgs,err)// 12. RPop当简单队列用第 18 篇讲为什么生产要用 Stream 替代returnrdb.RPop(ctx,queue:email).Err()}场景 4Set —— 共同关注与标签funcdemoSet(ctx context.Context,rdb*redis.Client)error{// 13. SAdd记录两个人的关注列表rdb.SAdd(ctx,follows:alice,bob,carol,dave)rdb.SAdd(ctx,follows:eve,carol,dave,frank)// 14. SInter共同关注 交集SISMEMBER 判断单个存在common,err:rdb.SInter(ctx,follows:alice,follows:eve).Result()fmt.Println(共同关注:,common,err)// [carol dave]// 15. SIsMember判断我是否关注了某人isFan,err:rdb.SIsMember(ctx,follows:alice,bob).Result()fmt.Println(alice 关注 bob:,isFan,err)// 16. SCard关注数returnrdb.SCard(ctx,follows:alice).Err()}场景 5ZSet —— 排行榜第 15 篇有完整的工程细节funcdemoZSet(ctx context.Context,rdb*redis.Client)error{key:rank:game:weekly// 17. ZAdd上报分数rdb.ZAdd(ctx,key,redis.Z{Score:2500,Member:player_A},redis.Z{Score:3100,Member:player_B})// 18. ZIncrBy玩家又赢了一局 100 分rdb.ZIncrBy(ctx,key,100,player_A)// 19. ZRevRangeWithScoresTop10分数从高到低top,err:rdb.ZRevRangeWithScores(ctx,key,0,9).Result()fmt.Println(Top10:,top,err)// 20. ZRevRank我的排名从 0 开始展示时 1rank,err:rdb.ZRevRank(ctx,key,player_A).Result()fmt.Println(player_A 排名:,rank1,err)returnerr}三、20 命令速查表收藏点 1命令结构时间复杂度一句话场景SETEXStringO(1)带 TTL 缓存对象GETStringO(1)读缓存redis.Nil 未命中SET NX PXStringO(1)分布式锁地基INCRStringO(1)原子计数HSETHashO(1)写对象字段HGETALLHashO(N)取整个对象大 Hash 慎用见第 22 篇HINCRBYHashO(1)字段级计数HDELHashO(1)删字段LPUSHListO(1)推到头部RPOPListO(1)简单队列出队LRANGEListO(SN)分页拉取LTRIMListO(N)截断防膨胀SADDSetO(1)去重集合SINTERSetO(N×M)共同关注SISMEMBERSetO(1)存在性判断SCARDSetO(1)集合大小ZADDZSetO(logN)上报分数ZINCRBYZSetO(logN)加分ZREVRANGEZSetO(logNM)TopNZREVRANKZSetO(logN)查排名复杂度是选结构的另一半理由凡是不是 O(1)/O(logN) 的命令HGETALL、SINTER、LRANGE 大范围在大 key 上都是定时炸弹第 21/22 篇专门拆。四、容易踩的 3 个坑redis.Nil不是错误Get 未命中返回redis.Nil要用errors.Is(err, redis.Nil)区分没数据和真故障混为一谈会把缓存未命中当成系统异常报警HGetAll 大 Hash 会阻塞10 万字段的 Hash 一次全取就是一次慢查询用 HScan 渐进遍历下一篇List 当队列没有 ACKRPop 拿走就丢了崩溃 丢消息第 18 篇用 Stream 解决。五、总结学命令的正确姿势场景 → 结构 → 命令反过来记不住5 个场景 20 个命令覆盖了日常开发的 80%选结构时看一眼复杂度非 O(1)/O(logN) 的命令在大 key 上有阻塞风险redis.Nil要与真错误分开处理。下一篇预告命令都会用了但有人把 key 起成a、b、c还有人凌晨在 5000 万 key 的库里跑KEYS *——下一篇《一条 KEYS * 把网关拖垮 30 秒——key 命名规范与 SCAN 渐进扫描的 Go 实现》聊聊 key 的工程化管理和安全遍历。
延伸阅读

更多相关文章

2026/10/11 8:47:52

当测试工程师遭遇算法占卜:AI测试工具实战与应对策略

代码神殿里的新祭司:当测试工程师遭遇算法占卜潮最近一个月,我身边至少有三位测试工程师跟我聊起同一个感受:以前写测试用例是靠经验和需求文档,现在打开编辑器,满屏都是AI生成的断言、Mock数据和场景分支,…

2026/10/11 8:47:52

基于.NET的Windows窗体编程之WinForms自定义控件(2)

在实际应用开发中,可能UI框架的默认控件,已经不能满足实际的应用需求,或者某些功能被大量的重复应用,如果每一个使用的地方都书写大量的重复代码,则不仅会浪费精力,且让维护变得复杂,此时就需要…

2026/10/11 8:47:52

三轴V90 PN与SMART200伺服控制:从PROFINET通信到调试实战

最近又接手一个三轴V90和一台SMART200的老项目,调试完顺手把这几年的经验重新捋了一遍。三轴V90 PN与SMART200,说白了就是三台西门子V90伺服驱动器通过PROFINET总线挂在一台S7-200 SMART的PLC下面,组成一套三轴运动控制系统。它的核心价值不在…

2026/10/11 12:08:05

造纸厂 AR 设备点检的技术实现路径与数据流设计

在造纸厂引入增强现实(AR)进行设备点检,核心效果在于将静态的纸质或电子表单转化为动态的、与物理设备实时绑定的可视化作业流,解决了传统巡检中“人到了但没看对”、“看了但没记准”以及“发现问题无法即时闭环”的三大痛点。通…

2026/10/11 12:08:05

免疫检查点抗体:如何精准靶向调控肿瘤免疫应答的关键分子?

免疫检查点是一类调节免疫反应强度、防止正常组织损伤的抑制性分子,在肿瘤微环境中常被肿瘤细胞利用以逃避免疫攻击。免疫检查点抗体作为特异性靶向这些分子的工具,能够阻断共抑制信号或激活共刺激信号,从而恢复或增强T细胞的抗肿瘤活性。目前…

2026/10/11 0:02:13

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/11 0:02:13

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/11 0:02:13

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/11 0:02:13

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/11 0:02:13

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/11 0:02:13

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑