第四章:Redis 数据结构与命令
📺 对应集数:p010p015(第914集)
第四章:Redis 数据结构与命令
4.1 数据结构概览
Redis 的 Value 支持多种数据类型:
基本类型(5 种):
- String(字符串):最简单的类型,Value 为普通字符串
- Hash(哈希):Value 为哈希表(类似 Java 的 HashMap)
- List(列表):有序集合,底层为双向链表
- Set(集合):无序集合,元素不重复
- SortedSet(有序集合):可排序的集合,根据 Score 排序
特殊类型(3 种):
- GEO:地理坐标
- BitMap:位图
- HyperLogLog:基数统计
4.2 通用命令
适用于所有数据类型的命令。
bash
# KEYS - 查找符合模式的所有 key(支持通配符 * ?)
KEYS * # 查找所有 key
KEYS a* # 查找以 a 开头的 key
KEYS *name* # 查找包含 name 的 key
KEYS user? # 查找 user 后面跟一个字符的 key
# ⚠️ 生产环境不建议使用 KEYS,因为模糊查询效率低,会阻塞 Redis
# 如需使用,建议在从节点上执行
# DEL - 删除指定的 key(可删一个或多个)
DEL name # 删除单个 key
DEL k1 k2 k3 # 删除多个 key,返回实际删除的数量
# EXISTS - 判断 key 是否存在
EXISTS name # 存在返回 1,不存在返回 0
# EXPIRE - 给 key 设置有效期(秒)
EXPIRE name 20 # name 有效期 20 秒,到期自动删除
# TTL - 查看 key 的剩余有效期
TTL name # 返回剩余秒数
# -1:永久有效
# -2:key 已被移除/不存在
# 正数:剩余秒数
# SELECT - 选择数据库(0-15)
SELECT 1 # 切换到 1 号库
SELECT 0 # 切换回 0 号库
4.3 String 类型命令
String 是 Redis 最基本的数据类型,Value 可以是字符串、整数、浮点数(最大 512MB)。
bash
# 基本操作
SET key value # 添加或修改一个 String 类型的键值对
GET key # 获取指定 key 的值
MSET k1 v1 k2 v2 k3 v3 # 批量添加多个键值对
MGET k1 k2 k3 # 批量获取多个 key 的值
# 数值自增操作(Value 必须是整数)
INCR age # 让整数值自增 1
INCRBY age 2 # 让整数值自增指定步长(如 2)
INCRBYFLOAT score 0.5 # 让浮点数值自增指定步长(无默认步长,必须指定)
# INCRBY 传负数可实现自减效果
# 组合命令
SETNX key value # 仅当 key 不存在时才添加(存在则不执行,返回 0)
# SET NX 的组合,真正的「新增」功能
SET key value NX # 效果同 SETNX
SET key value EX 10 # SET + EXPIRE 的组合,添加并设置有效期为 10 秒
Key 的层级格式(最佳实践):
Redis 没有表的概念,所有 key 存在一起。推荐使用冒号分隔形成层级结构:
项目名:业务名:类型:ID
示例:
heima:user:1 # ID 为 1 的用户信息(Value 为 JSON 字符串)
heima:product:1 # ID 为 1 的商品信息
存储 Java 对象的示例:
bash
SET heima:user:1 '{"name":"Jack","age":21,"sex":"male"}'
SET heima:user:2 '{"name":"Lucy","age":18,"sex":"female"}'
4.4 Hash 类型命令
Hash 类型的 Value 是一个哈希表(类似 Java 的 HashMap),可以独立操作每个字段。
与 String 存储对象的对比:
- String:整个对象序列化为 JSON 字符串,修改单个字段不方便
- Hash:每个字段独立存储,可单独修改某个字段
bash
# 基本操作
HSET key field value # 添加/修改哈希表中一个字段
HGET key field # 获取哈希表中一个字段的值
HMSET key f1 v1 f2 v2 f3 v3 # 批量添加多个字段
HMGET key f1 f2 f3 # 批量获取多个字段的值
# 获取所有信息
HGETALL key # 获取哈希表中所有字段和值(返回 field-value 交替排列)
HKEYS key # 获取所有字段名
HVALS key # 获取所有字段值
# 自增操作
HINCRBY key field increment # 让哈希表中某个字段的整数值自增
# 示例:HINCRBY heima:user:4 age 2 # age 字段自增 2
# 组合命令
HSETNX key field value # 仅当字段不存在时才添加
存储示例:
bash
HMSET heima:user:3 name Lucy age 21 sex female
HGETALL heima:user:3
# 返回: name Lucy age 21 sex female
# 单独修改某个字段
HSET heima:user:3 age 17
4.5 List 类型命令
List 类型的 Value 是有序列表(类似 Java 的 LinkedList),底层为双向链表。
特征:
- 有序(与插入顺序有关)
- 元素可重复
- 插入和删除速度快
- 查询速度相对较慢
使用场景:对顺序有要求的数据,如朋友圈点赞列表、评论列表。
bash
# 插入操作(push)
LPUSH key e1 e2 e3 # 从左侧(头部)插入元素
RPUSH key e1 e2 e3 # 从右侧(尾部)插入元素
# 移除并返回操作(pop)
LPOP key [count] # 从左侧移除并返回元素
RPOP key [count] # 从右侧移除并返回元素
# 阻塞式获取(BLPOP/BRPOP)
BLPOP key timeout # 阻塞式从左侧获取,timeout 为超时秒数
BRPOP key timeout # 阻塞式从右侧获取,timeout 为超时秒数
# 当列表为空时会阻塞等待,有元素插入或超时后返回
# 范围查询
LRANGE key start stop # 获取指定脚标范围内的所有元素
# 示例:LRANGE users 0 2 获取脚标 0 到 2 的元素
# 获取长度
LLEN key # 获取列表长度
模拟栈和队列:
栈(先进后出):入口和出口在同一侧
- LPUSH + LPOP(都在左侧)
- RPUSH + RPOP(都在右侧)
队列(先进先出):入口和出口在不同侧
- LPUSH + RPOP(左侧进右侧出)
- RPUSH + LPOP(右侧进左侧出)
阻塞队列:在队列基础上使用 BLPOP/BRPOP
4.6 Set 类型命令
Set 类型的 Value 是无序集合(类似 Java 的 HashSet),底层为哈希表。
特征:
- 无序
- 元素不重复
- 查找速度快
- 支持交集、并集、差集运算
使用场景:好友列表、共同好友、关注列表等社交功能。
bash
# 基本操作
SADD key m1 m2 m3 # 向集合中添加一个或多个元素
SREM key m1 m2 # 从集合中移除一个或多个元素
SMEMBERS key # 获取集合中所有元素
SCARD key # 获取集合中元素的总个数
SISMEMBER key member # 判断某个元素是否在集合中(在返回 1,不在返回 0)
# 集合运算
SINTER key1 key2 # 求交集(两个集合共有的元素)
SDIFF key1 key2 # 求差集(key1 中有但 key2 中没有的元素)
SUNION key1 key2 # 求并集(两个集合所有元素合并去重)
实战示例(好友关系):
bash
# 张三的好友
SADD zs lisi wangwu zhaoliu
# 李四的好友
SADD ls wangwu mazi ergou
# 共同好友(交集)
SINTER zs ls # 返回: wangwu
# 张三独有好友(差集)
SDIFF zs ls # 返回: lisi zhaoliu
# 所有好友(并集)
SUNION zs ls # 返回: lisi wangwu zhaoliu mazi ergou
# 判断好友关系
SISMEMBER zs lisi # 1(张三有李四)
SISMEMBER ls zs_key # 0(李四没有张三)
# 删除好友
SREM zs lisi
4.7 SortedSet 类型命令
SortedSet 是可排序的集合,每个元素关联一个 Score(分数),根据 Score 排序。
底层结构:跳表(用于排序)+ 哈希表(用于查重)
特征:
- 可排序(根据 Score)
- 元素不重复
- 查询速度快
使用场景:排行榜功能(如热搜榜、积分榜)。
bash
# 基本操作
ZADD key score1 m1 score2 m2 ... # 添加元素及分数
ZREM key m1 m2 # 删除一个或多个元素
ZSCORE key member # 获取某个元素的分数
ZRANK key member # 获取某个元素的升序排名(从 0 开始)
ZREVRANK key member # 获取某个元素的降序排名(从 0 开始)
ZCARD key # 获取元素总个数
# 自增分数
ZINCRBY key increment member # 让某个元素的分数增加(传负数则减)
# 范围查询(按排名)
ZRANGE key min max # 按分数升序,获取排名范围内的元素
ZREVRANGE key min max # 按分数降序,获取排名范围内的元素
# 示例:ZREVRANGE students 0 2 获取前三名
# 范围查询(按分数值)
ZRANGEBYSCORE key min max # 获取分数在指定范围内的元素
# 示例:ZRANGEBYSCORE students 0 80 获取 0-80 分的元素
# 范围计数
ZCOUNT key min max # 获取分数在指定范围内的元素个数
# 示例:ZCOUNT students 0 80 获取 80 分以下的有多少人
# 集合运算
ZINTERSTORE dest numkeys k1 k2 ... # 交集
ZUNIONSTORE dest numkeys k1 k2 ... # 并集
实战示例(学生成绩排行榜):
bash
# 添加学生成绩
ZADD students 85 Jack 89 Lucy 82 Rose 95 Tom 78 Jerry 92 Amy 76 Miles
# 删除 Tom
ZREM students Tom
# 获取 Rose 的排名(降序)
ZREVRANK students Rose # 返回排名(从 0 开始,实际排名需 +1)
# 统计 80 分以下的学生数
ZCOUNT students 0 80
# Amy 加 2 分
ZINCRBY students 2 Amy
# 获取前三名(降序)
ZREVRANGE students 0 2
# 获取 80 分以下的学生(按分数范围)
ZRANGEBYSCORE students 0 80