Redis 数据结构
Redis 其实就是个 “超级储物间”,里面有 5 种不同的 “盒子”,每种盒子有自己的脾气 —— 有的适合存零散纸条,有的适合存通讯录,有的适合排队放东西…… 咱们一个个打开看:
一、String:“便利贴盒子”—— 存单个小物件最方便
样子:就像一叠便利贴,每张便利贴只能写一行字(或一个数字),贴的时候要写个名字(key)。
能存啥:
- 一句话(比如 “张三的手机号是 138xxx”);
- 一个数字(比如 “李四的积分是 100”);
- 甚至一张小图片(把图片转成二进制,像写密文一样存进去)。
怎么用:
- 存东西:
set 便利贴名字 内容
比如存验证码:set code:138xxx 6379
(给手机号 138xxx 贴一张写着 6379 的便利贴)。 - 取东西:
get 便利贴名字
比如取验证码:get code:138xxx
→ 得到 6379。 - 数字专用:
incr 便利贴名字
(自动 + 1)
比如计数:incr view:视频123
→ 每次有人看视频,这张便利贴的数字就 + 1。
适合场景:
- 存临时信息(验证码、登录 token);
- 计数(播放量、点赞数);
- 简单的缓存(比如存一条商品简介)。
二、Hash:“通讯录盒子”—— 存 “多属性对象” 最整齐
样子:像一本通讯录,封面写个名字(key),里面每一页是 “姓名 - 电话”“地址 - 邮编” 这样的成对信息(field-value)。
能存啥:
- 有多个属性的东西,比如一个人(姓名、年龄、地址)、一件商品(名称、价格、库存)。
怎么用:
- 存东西:
hset 通讯录名字 属性名 属性值
比如存用户信息:hset user:100 姓名 张三 年龄 28 地址 北京
(给 “user:100” 这本通讯录加 3 条信息)。 - 取东西:
hget 通讯录名字 属性名
比如取年龄:hget user:100 年龄
→ 得到 28。 - 取所有:
hgetall 通讯录名字
→ 一下子拿出这本通讯录里的所有信息。
为啥不用多个便利贴(String)?
如果用 String 存用户信息,得贴 3 张便利贴:user:100:姓名 张三
、user:100:年龄 28
…… 看着乱,改的时候还得一张张找。用 Hash 一本通讯录就搞定,整齐又好改。
适合场景:
- 存用户、商品等多属性对象;
- 购物车(比如
hset cart:100 商品A 2 商品B 1
,存 “用户 100 的购物车有 2 个 A、1 个 B”)。
三、List:“传送带盒子”—— 按顺序存东西,取的时候能排队
样子:像工厂的传送带,东西可以从左边放上去(lpush
),也可以从右边放上去(rpush
);取的时候可以从左边拿(lpop
),也可以从右边拿(rpop
)。
能存啥:
- 要按顺序处理的东西,比如消息、待办事项、最新评论。
怎么用:
- 左边放东西:
lpush 传送带名字 内容
比如存消息:lpush msg:queue 消息1 消息2
→ 传送带左边先放消息 1,再放消息 2(现在顺序是 “消息 2、消息 1”)。 - 右边拿东西:
rpop 传送带名字
→ 从右边拿出最老的消息 1。 - 看中间的东西:
lrange 传送带名字 0 1
→ 看前 2 个东西(消息 2、消息 1)。
特别技能:
- 阻塞拿东西:
brpop 传送带名字 30
→ 如果传送带上没东西,就等 30 秒,有东西了立刻拿(适合做消息队列,不用一直问 “有东西吗?有东西吗?”)。
适合场景:
- 消息队列(比如用户下单后,消息放进传送带,后台程序一个个拿出来处理);
- 最新列表(比如 “最新 5 条评论”,新评论从左边放,取的时候看前 5 个)。
四、Set:“去重水果篮”—— 装不重复的东西,还能找交集
样子:像家里的水果篮,你可以往里放苹果、香蕉,但同一类水果只能放一个(比如不能放两个苹果);还能和另一个水果篮比,找出都有的水果(交集)。
能存啥:
- 不重复的标签、ID、名称,比如用户的兴趣标签、抽奖的参与者。
怎么用:
- 放东西:
sadd 水果篮名字 东西
比如存用户兴趣:sadd user:100:hobby 篮球 音乐 电影
→ 水果篮里有篮球、音乐、电影(再放一次篮球也不会多出来)。 - 看所有东西:
smembers 水果篮名字
→ 列出所有兴趣。 - 找两个篮子的共同东西:
sinter 水果篮1 水果篮2
比如user:100
喜欢篮球、音乐,user:200
喜欢音乐、电影,sinter
后得到 “音乐”(共同兴趣)。
适合场景:
- 去重(比如 “参与抽奖的用户 ID”,避免重复抽奖);
- 标签系统(用户兴趣、商品分类);
- 社交(共同好友、共同关注)。
五、Zset:“带分数的排行榜”—— 能排序的特殊水果篮
样子:像学校的成绩单,每个学生(东西)后面都跟着一个分数,能按分数从高到低排(比如 “张三 90 分、李四 80 分”)。
能存啥:
- 需要排序的东西,比如排行榜、带优先级的任务。
怎么用:
- 放东西(带分数):
zadd 排行榜名字 分数 东西
比如存游戏排名:zadd game:rank 1000 玩家A 900 玩家B 800 玩家C
→ 成绩单上玩家 A1000 分、B900 分、C800 分。 - 按分数从高到低看前 2 名:
zrevrange 排行榜名字 0 1
→ 得到玩家 A、玩家 B。 - 给某个东西加分:
zincrby 排行榜名字 100 玩家B
→ 玩家 B 的分数变成 1000 分(超过 A)。
和 List 的区别:
List 只能按 “放进去的顺序” 排,Zset 能按 “自己定的分数” 排(比如想让谁排第一,就给他高分)。
适合场景:
- 各种排行榜(游戏得分、视频热度、销售榜单);
- 带优先级的任务(比如 “紧急任务分数 100,普通任务分数 50”,先处理高分任务)。
总结:5 种盒子怎么选?
盒子名字(数据结构) | 生活类比 | 拿手好戏 | 一句话记住它 |
---|---|---|---|
String | 便利贴 | 存单个小物件、计数 | 存一个,用它就对了 |
Hash | 通讯录 | 存多属性对象(用户、商品) | 存对象,用它整齐 |
List | 传送带 | 按顺序存,适合排队、消息 | 要排队,用它方便 |
Set | 去重水果篮 | 存不重复的东西,找交集 | 要去重,用它靠谱 |
Zset | 带分数的排行榜 | 能按分数排序,做排名 | 要排序,用它灵活 |