Redis 数据类型与业务场景详解

tanqi
10
2025-04-13

Redis 提供了丰富的数据类型,每种类型基于不同的数据结构设计,适用于特定的业务场景。以下是对 HashSetListStringZSET(有序集合)的详细解析:

1. Hash 类型

数据结构特点

  • 键值对的集合key 是主键,value 是包含多个字段(field)和值(value)的字典,即 key: {field1: value1, field2: value2, ...}

  • 底层实现:字段较少时使用压缩列表(ziplist),字段较多时切换为哈希表(hashtable),兼顾内存效率和访问速度。

典型应用场景

存储对象:例如商品详情(商品 ID 为 key,字段包含 namepricestock 等),支持字段级操作。

HSET product:1001 name "iPhone 15" price 5999 stock 100  # 存储字段
HGET product:1001 price  # 获取单个字段
HGETALL product:1001  # 获取所有字段

  • 用户信息管理:用户 ID 为 key,存储 usernameemailcreate_time 等字段。

  • 配置管理:存储系统配置项,支持动态更新部分字段。

核心操作命令

命令

描述

示例

HSET key field value

设置单个字段的值

HSET user:1001 username Alice

HGET key field

获取单个字段的值

HGET user:1001 username

HGETALL key

获取所有字段和值

HGETALL user:1001

HDEL key field

删除指定字段

HDEL user:1001 email

HINCRBY key field incr

对数值型字段递增指定值

HINCRBY product:1001 stock -5

优势

  • 字段级操作高效:无需序列化 / 反序列化整个对象,直接操作单个字段。

  • 内存友好:字段较少时使用压缩列表,节省内存空间。

2. Set 类型

数据结构特点

  • 无序、唯一的元素集合:元素不重复,支持 O (1) 时间复杂度的成员存在性检查。

  • 底层实现:元素为整数时使用整数集合(intset),否则使用哈希表(hashtable)。

典型应用场景

  • 集合运算:交集(SINTER)、并集(SUNION)、差集(SDIFF),例如:

    • 共同好友SINTER user:1:friends user:2:friends 获取两人的共同好友。

    • 标签筛选:通过交集筛选同时包含多个标签的商品。

  • 去重与唯一性校验:统计网站独立访客(SADD uv:20250412 user1 user2...SCARD 计算总数)。

  • 随机抽取SRANDMEMBER 从集合中随机获取元素(如抽奖场景)。

核心操作命令

命令

描述

示例

SADD key member [member ...]

向集合中添加元素(去重)

SADD user:1:friends A B C

SREM key member [member ...]

从集合中删除元素

SREM user:1:friends B

SINTER key1 key2

计算多个集合的交集

SINTER friends:alice friends:bob

SRANDMEMBER key [count]

随机获取指定数量的元素

SRANDMEMBER lucky_draw 3

SCARD key

获取集合中元素的数量

SCARD uv:20250412

优势

  • 天然支持集合运算:高效实现交集、并集、差集操作,适用于社交、推荐系统。

  • 去重特性:自动过滤重复元素,避免冗余存储。

3. List 类型

数据结构特点

  • 双向链表:有序、可重复,支持从头部(左)或尾部(右)插入 / 删除元素。

  • 底层实现:元素较少时使用压缩列表(ziplist),较多时使用优化的双向链表(quicklist)。

典型应用场景

  • 队列(FIFO):左进右出(LPUSH + RPOP),用于任务队列、消息异步处理。

  • 栈(LIFO):左进左出(LPUSH + LPOP),实现操作历史回溯。

  • 列表展示:按顺序存储数据,如最新评论(LPUSH 插入新评论,LRANGE 0 9 获取前 10 条)。

  • 分页查询:通过 LRANGE key start end 实现高效分页。

核心操作命令

命令

描述

示例

LPUSH key value [value ...]

从头部插入元素

LPUSH queue:task "job1" "job2"

RPOP key

从尾部弹出元素

RPOP queue:task

LRANGE key start end

获取指定范围的元素(索引从 0 开始)

LRANGE comments:1001 0 9

LLEN key

获取列表长度

LLEN queue:task

LREM key count value

删除指定数量的元素(count>0从头部删,count<0从尾部删)

LREM queue:task -1 "job2"

优势

  • 双向操作灵活:支持头部和尾部快速增删,适合队列、栈场景。

  • 范围查询高效LRANGE 直接通过索引定位,无需全量扫描。

4. String 类型

数据结构特点

  • 最基础类型:存储字符串或二进制数据(最大 512MB),支持原子操作(保证操作的原子性)。

典型应用场景

  • 简单键值对存储:缓存用户登录态(SET user:1001:token abc123 ex 3600)。

计数器:利用 INCR/INCRBY 实现原子递增(如点赞数、接口调用次数)。

INCR post:1001:like  # 点赞数+1
GET post:1001:like  # 获取当前点赞数

  • 分布式锁:通过 SETNX key value ex 10 实现简单锁(仅当键不存在时设置)。

  • 位操作SETBIT/GETBIT 存储二进制状态(如用户登录状态统计,BITCOUNT 计算活跃用户数)。

核心操作命令

命令

描述

示例

SET key value [EX seconds]

设置键值对(可指定过期时间)

SET cache:user 123 ex 3600

GET key

获取键对应的值

GET cache:user

INCR key

对数值型值递增 1

INCR api:counter

SETBIT key offset value

设置二进制位的值(0 或 1)

SETBIT online:users 1001 1

BITCOUNT key

统计二进制位中 1 的数量

BITCOUNT online:users

优势

  • 适用范围广:支持字符串、数值、二进制数据,是缓存和计数器的首选。

  • 原子性保证:所有操作均为原子性,确保并发场景下的数据一致性。

5. ZSET(有序集合)类型

数据结构特点

  • 有序、唯一的元素集合:每个元素(member)关联一个 分数(score),按分数升序或降序排序。

  • 底层实现:元素较少时用压缩列表(ziplist),较多时用跳表(skiplist)+ 哈希表(跳表保证有序,哈希表保证 O (1) 存在性检查)。

典型应用场景

排行榜 / 排名系统:实时更新用户分数排名(如游戏段位、销量榜),支持分数范围查询和排名获取。

ZADD rank:game 900 user:A 850 user:B  # 插入分数  
ZREVRANGE rank:game 0 9 WITHSCORES  # 降序获取前10名及分数  

  • 带权重的任务队列:分数代表优先级,ZPOPMAX/ZPOPMIN 取出最高 / 最低优先级任务(Redis 6.2+)。

  • 时间线 / 最近访问记录:时间戳作为分数,ZREVRANGE 获取最近访问的 N 条记录。

  • 地理围栏:结合 GEORADIUS 命令,按经纬度距离排序(本质是 ZSET 的扩展应用)。

核心操作命令

命令

描述

示例

ZADD key score member [score member ...]

插入元素及分数(可批量)

ZADD rank:game 900 A 850 B

ZREVRANGE key start end [WITHSCORES]

按分数降序获取指定范围的元素

ZREVRANGE rank:game 0 9

ZINCRBY key incr member

对元素的分数增加指定增量

ZINCRBY rank:game 50 A

ZRANK key member

获取元素的升序排名(从 0 开始)

ZRANK rank:game A

ZCOUNT key min max

统计分数在 [min, max] 范围内的元素数量

ZCOUNT rank:game 800 1000

优势

  • 有序性与唯一性结合:既保证元素不重复,又能按分数动态排序。

  • 高效范围查询:跳表实现 O (log N) 时间复杂度的排名和范围查询。

  • 动态更新友好:支持实时调整分数(如 ZINCRBY),自动重新排序。

总结对比

类型

数据结构

有序性

唯一性

元素关联值

典型场景

核心优势

Hash

字段 - 值字典

无序

字段唯一

字段 - 值对

对象存储、配置管理

字段级操作高效

Set

无序唯一集合

无序

唯一

无(元素本身)

共同好友、标签筛选

集合运算高效、去重

List

双向链表

有序

可重复

无(元素本身)

任务队列、时间线展示

双向操作、范围查询高效

String

字符串 / 二进制数据

键唯一

字符串 / 数值

缓存、计数器、分布式锁

原子操作、位操作支持

ZSET

有序唯一集合

有序

唯一

分数(score)

排行榜、优先级队列

按分数排序、范围查询高效


根据业务需求(如是否需要顺序、唯一性、复杂运算)选择合适的数据类型,可显著提升 Redis 的使用效率和性能。

动物装饰