跳到主要内容

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有序,支持范围查询
计数器StringINCR/DECR 操作
购物车Hash商品 ID 作为字段
时间线List/Sorted Set按时间排序
签到Set/BitmapSet 简单,Bitmap 省内存

小结

  1. String:最基本类型,适合缓存、计数器、分布式锁
  2. Hash:字段-值对,适合存储对象
  3. List:有序列表,适合消息队列、时间线
  4. Set:无序集合,适合标签、关注关系
  5. Sorted Set:有序集合,适合排行榜、延迟队列

练习

  1. 使用 String 实现一个文章阅读计数器
  2. 使用 Hash 存储用户信息,并实现字段级别的更新
  3. 使用 List 实现一个简单的消息队列
  4. 使用 Set 实现用户标签系统,并计算共同标签
  5. 使用 Sorted Set 实现一个游戏排行榜