Redis 数据类型
Redis 支持五种基本数据类型:字符串(String)、哈希(Hash)、列表(List)、集合(Set)和有序集合(Sorted Set)。理解这些数据类型及其特点,是使用 Redis 的基础。
字符串(String)
字符串是 Redis 最基本的数据类型,可以存储字符串、整数或二进制数据。
特点
- 二进制安全,可以存储任何数据
- 最大容量 512MB
- 支持数值操作
基本操作
# 设置值
SET key value
SET user:1 "张三"
# 获取值
GET key
GET user:1 # "张三"
# 设置值并设置过期时间(秒)
SETEX key seconds value
SETEX session:abc 3600 "user_data"
# 设置值,仅当 key 不存在时
SETNX key value
SETNX lock:resource "locked" # 返回 1 表示设置成功
# 批量设置
MSET key1 value1 key2 value2
MSET user:1:name "张三" user:1:age "25"
# 批量获取
MGET key1 key2
MGET user:1:name user:1:age
数值操作
# 设置数值
SET counter 100
# 递增
INCR counter # 101
INCRBY counter 10 # 111
# 递减
DECR counter # 110
DECRBY counter 10 # 100
# 浮点数递增
SET price 10.50
INCRBYFLOAT price 2.30 # "12.8"
字符串操作
# 追加字符串
SET msg "Hello"
APPEND msg " World" # 返回长度 11
GET msg # "Hello World"
# 获取字符串长度
STRLEN msg # 11
# 获取子串
GETRANGE msg 0 4 # "Hello"
# 设置子串
SETRANGE msg 6 "Redis" # "Hello Redis"
应用场景
# 缓存用户信息
SET user:1001 '{"name":"张三","age":25,"city":"北京"}'
# 计数器
INCR article:123:views
# 分布式锁
SET lock:order:123 "uuid" NX PX 30000
# 分布式 ID 生成
INCR global:order:id
哈希(Hash)
哈希是一个键值对集合,适合存储对象。
特点
- 存储字段-值对
- 适合存储对象
- 内存效率高
基本操作
# 设置单个字段
HSET user:1 name "张三"
HSET user:1 age 25
# 设置多个字段
HMSET user:2 name "李四" age 30 city "上海"
# 获取单个字段
HGET user:1 name # "张三"
# 获取多个字段
HMGET user:1 name age
# 1) "张三"
# 2) "25"
# 获取所有字段和值
HGETALL user:1
# 1) "name"
# 2) "张三"
# 3) "age"
# 4) "25"
# 获取所有字段名
HKEYS user:1 # 1) "name" 2) "age"
# 获取所有值
HVALS user:1 # 1) "张三" 2) "25"
# 检查字段是否存在
HEXISTS user:1 name # 1
# 删除字段
HDEL user:1 age
# 获取字段数量
HLEN user:1
数值操作
# 字段值递增
HSET user:1 score 100
HINCRBY user:1 score 10 # 110
HINCRBYFLOAT user:1 score 5.5 # "115.5"
条件设置
# 仅当字段不存在时设置
HSETNX user:1 name "王五" # 0,因为 name 已存在
HSETNX user:1 email "[email protected]" # 1
应用场景
# 存储用户信息
HSET user:1001 name "张三" age 25 email "[email protected]"
# 存储商品信息
HSET product:2001 name "iPhone 15" price 7999 stock 100
# 购物车
HSET cart:user:1001 product:2001 2 product:2002 1
HINCRBY cart:user:1001 product:2001 1 # 增加商品数量
# 计数器
HINCRBY stats:2024-01-01 page_views 1
HINCRBY stats:2024-01-01 unique_visitors 1
列表(List)
列表是一个有序的字符串列表,按插入顺序排序。
特点
- 有序可重复
- 支持两端操作
- 可作为队列或栈使用
基本操作
# 左侧插入
LPUSH mylist "a" "b" "c" # 返回列表长度 3
# 列表内容: ["c", "b", "a"]
# 右侧插入
RPUSH mylist "d" "e" # 返回列表长度 5
# 列表内容: ["c", "b", "a", "d", "e"]
# 获取列表长度
LLEN mylist # 5
# 获取范围内的元素
LRANGE mylist 0 -1 # 获取所有元素
LRANGE mylist 0 2 # 获取前三个元素
# 获取指定索引的元素
LINDEX mylist 0 # "c"
LINDEX mylist -1 # "e"
# 左侧弹出
LPOP mylist # "c"
# 右侧弹出
RPOP mylist # "e"
# 阻塞弹出(用于消息队列)
BLPOP mylist 5 # 5秒超时
BRPOP mylist 5
修改操作
# 设置指定索引的值
LSET mylist 0 "new_value"
# 在指定元素前/后插入
LINSERT mylist BEFORE "a" "before_a"
LINSERT mylist AFTER "a" "after_a"
# 删除指定数量的元素
LREM mylist 2 "a" # 删除 2 个 "a"
# 保留指定范围内的元素
LTRIM mylist 0 9 # 只保留前 10 个元素
应用场景
# 消息队列
LPUSH queue:email "email_data_1"
LPUSH queue:email "email_data_2"
RPOP queue:email # 消费消息
# 最新消息列表
LPUSH news:latest "news_id_1"
LPUSH news:latest "news_id_2"
LRANGE news:latest 0 9 # 获取最新 10 条
# 时间线
LPUSH timeline:user:1 "post:100"
LPUSH timeline:user:1 "post:101"
LRANGE timeline:user:1 0 20 # 获取最近 20 条动态
# 分页获取
LRANGE articles 0 9 # 第 1 页
LRANGE articles 10 19 # 第 2 页
集合(Set)
集合是无序的唯一字符串集合。
特点
- 无序不重复
- 支持集合运算
- 高效的成员检测
基本操作
# 添加元素
SADD myset "a" "b" "c" # 返回添加的元素数量
# 获取所有元素
SMEMBERS myset # 1) "a" 2) "b" 3) "c"
# 检查元素是否存在
SISMEMBER myset "a" # 1
# 删除元素
SREM myset "a"
# 获取集合大小
SCARD myset
# 随机获取元素
SRANDMEMBER myset # 随机返回一个元素
SRANDMEMBER myset 2 # 随机返回 2 个元素
# 随机弹出元素
SPOP myset
集合运算
# 创建两个集合
SADD set1 "a" "b" "c"
SADD set2 "b" "c" "d"
# 交集
SINTER set1 set2 # 1) "b" 2) "c"
# 并集
SUNION set1 set2 # 1) "a" 2) "b" 3) "c" 4) "d"
# 差集
SDIFF set1 set2 # 1) "a"
# 将结果存储到新集合
SINTERSTORE result set1 set2
SUNIONSTORE result set1 set2
SDIFFSTORE result set1 set2
应用场景
# 标签系统
SADD article:1:tags "redis" "database" "nosql"
SADD article:2:tags "redis" "cache"
# 获取共同标签
SINTER article:1:tags article:2:tags # "redis"
# 用户关注系统
SADD user:1:following user:2 user:3
SADD user:2:followers user:1
# 共同关注
SINTER user:1:following user:2:following
# 可能认识的人(我关注的人的关注)
SDIFF user:2:following user:1:following
# 抽奖系统
SADD lottery:2024 user:1 user:2 user:3
SPOP lottery:2024 # 随机抽取中奖者
# 签到系统
SADD sign:2024-01-01 user:1 user:2
SCARD sign:2024-01-01 # 当日签到人数
有序集合(Sorted Set)
有序集合是带分数的有序集合,每个元素关联一个分数。
特点
- 有序不重复
- 元素关联分数
- 支持范围查询
基本操作
# 添加元素
ZADD leaderboard 100 "user1" 200 "user2" 150 "user3"
# 获取元素分数
ZSCORE leaderboard "user1" # "100"
# 获取排名(从 0 开始,分数从低到高)
ZRANK leaderboard "user1" # 0
# 获取排名(分数从高到低)
ZREVRANK leaderboard "user2" # 0
# 递增分数
ZINCRBY leaderboard 50 "user1" # "150"
# 获取集合大小
ZCARD leaderboard
# 获取分数范围内的元素数量
ZCOUNT leaderboard 100 200
范围查询
# 按排名范围获取(分数从低到高)
ZRANGE leaderboard 0 2 # 前 3 名(分数最低)
ZRANGE leaderboard 0 -1 # 所有元素
# 按排名范围获取(分数从高到低)
ZREVRANGE leaderboard 0 2 # 前 3 名(分数最高)
# 按分数范围获取
ZRANGEBYSCORE leaderboard 100 200
ZRANGEBYSCORE leaderboard (100 200 # 不包含 100
ZRANGEBYSCORE leaderboard -inf +inf # 所有元素
# 带分数返回
ZRANGE leaderboard 0 -1 WITHSCORES
ZREVRANGE leaderboard 0 -1 WITHSCORES
删除操作
# 删除元素
ZREM leaderboard "user1"
# 按排名范围删除
ZREMRANGEBYRANK leaderboard 0 2
# 按分数范围删除
ZREMRANGEBYSCORE leaderboard 0 100
集合运算
# 创建两个有序集合
ZADD set1 1 "a" 2 "b" 3 "c"
ZADD set2 2 "b" 3 "c" 4 "d"
# 并集(合并分数)
ZUNIONSTORE result 2 set1 set2
# 并集(自定义权重)
ZUNIONSTORE result 2 set1 set2 WEIGHTS 1 2
# 并集(自定义聚合方式)
ZUNIONSTORE result 2 set1 set2 AGGREGATE SUM|MIN|MAX
# 交集
ZINTERSTORE result 2 set1 set2
应用场景
# 排行榜
ZADD game:leaderboard 10000 "player1" 8500 "player2"
ZREVRANGE game:leaderboard 0 9 WITHSCORES # 前 10 名
# 延迟队列
ZADD delay:queue 1704067200 "task:1" # 时间戳作为分数
ZRANGEBYSCORE delay:queue 0 1704067200 # 获取到期任务
# 热榜
ZINCRBY hot:topics 1 "topic:1" # 增加热度
ZREVRANGE hot:topics 0 9 # 热门话题
# 带权重的标签
ZADD user:1:interests 10 "redis" 8 "mysql" 5 "python"
ZREVRANGE user:1:interests 0 -1 # 按兴趣程度排序
# 时间线(按时间排序)
ZADD timeline:user:1 1704067200 "post:1"
ZADD timeline:user:1 1704067260 "post:2"
ZREVRANGE timeline:user:1 0 20 # 最新 20 条
数据类型选择指南
| 场景 | 推荐类型 | 说明 |
|---|---|---|
| 简单缓存 | String | 直接存储序列化数据 |
| 对象存储 | Hash | 字段级别操作,内存效率高 |
| 消息队列 | List | 有序,支持阻塞操作 |
| 标签/去重 | Set | 自动去重,支持集合运算 |
| 排行榜 | Sorted Set | 有序,支持范围查询 |
| 计数器 | String | INCR/DECR 操作 |
| 购物车 | Hash | 商品 ID 作为字段 |
| 时间线 | List/Sorted Set | 按时间排序 |
| 签到 | Set/Bitmap | Set 简单,Bitmap 省内存 |
小结
- String:最基本类型,适合缓存、计数器、分布式锁
- Hash:字段-值对,适合存储对象
- List:有序列表,适合消息队列、时间线
- Set:无序集合,适合标签、关注关系
- Sorted Set:有序集合,适合排行榜、延迟队列
练习
- 使用 String 实现一个文章阅读计数器
- 使用 Hash 存储用户信息,并实现字段级别的更新
- 使用 List 实现一个简单的消息队列
- 使用 Set 实现用户标签系统,并计算共同标签
- 使用 Sorted Set 实现一个游戏排行榜