📝 引言

“工欲善其事,必先利其器。”

在当今这个数据如洪水般涌来的时代,如何高效地存储和操作数据,几乎成了每个开发者的"必修课"。而Redis,这位数据库领域的"闪电侠",凭借其飞一般的速度和丰富的数据结构,早已成为众多系统架构中的"中流砥柱"。

你是否曾为缓存失效而抓耳挠腮?是否为实时排行榜的实现而绞尽脑汁?是否想知道如何用几行命令就能搞定百万级用户的签到统计?别慌,就像《人月神话》里说的:“没有银弹”,但Redis绝对是你解决这些问题的"瑞士军刀"。

本文将带你深入浅出地探索Redis的8大数据类型,从最基础的字符串到高级的地理位置功能,每个类型都配备了详细的命令示例和实际应用场景。无论你是刚接触Redis的新手,还是想进阶的老司机,相信都能从中找到宝藏。

📑 全文目录

Redis 是一个高性能的键值存储系统,支持多种数据类型。本文将详细介绍 Redis 支持的主要数据类型及其常用操作命令,并提供丰富的代码示例。

一、字符串 (String)

字符串是 Redis 最基本的数据类型,可以存储二进制数据、JSON、序列化对象等,最大容量为 512MB。

基本操作命令

# 设置键值
SET key value
# 示例:设置用户名为 "zhangsan" 的用户ID为 1001
SET user:1001:name "zhangsan"

# 获取键值
GET key
# 示例:获取用户ID为 1001 的用户名
GET user:1001:name

# 设置键值并指定过期时间(秒)
SET key value EX seconds
# 示例:设置一个 10 秒后过期的临时缓存
SET temp:cache "临时数据" EX 10

# 设置键值并指定过期时间(毫秒)
SET key value PX milliseconds
# 示例:设置一个 5000 毫秒后过期的临时缓存
SET temp:cache "临时数据" PX 5000

# 仅当键不存在时设置
SETNX key value
# 示例:分布式锁实现
SETNX lock:resource 1

# 设置多个键值
MSET key1 value1 key2 value2 ...
# 示例:一次设置多个用户信息
MSET user:1001:name "zhangsan" user:1001:age 25

# 获取多个键值
MGET key1 key2 ...
# 示例:一次获取多个用户信息
MGET user:1001:name user:1001:age

# 键值递增
INCR key
# 示例:计数器加1
INCR page:views

# 键值递增指定步长
INCRBY key increment
# 示例:计数器加5
INCRBY page:views 5

# 键值递减
DECR key
# 示例:计数器减1
DECR stock:items

# 键值递减指定步长
DECRBY key decrement
# 示例:计数器减3
DECRBY stock:items 3

# 向字符串追加内容
APPEND key value
# 示例:追加用户备注信息
APPEND user:1001:note "VIP客户"

# 获取字符串长度
STRLEN key
# 示例:获取用户名长度
STRLEN user:1001:name

应用场景

  • 缓存用户会话信息
  • 计数器(访问量、点赞数等)
  • 分布式锁实现
  • 存储序列化对象

二、列表 (List)

Redis 列表是简单的字符串列表,按照插入顺序排序,可以在列表的头部或尾部添加元素,底层实现是双向链表。

基本操作命令

# 在列表头部添加元素
LPUSH key element [element ...]
# 示例:向消息队列头部添加消息
LPUSH message:queue "message1" "message2"

# 在列表尾部添加元素
RPUSH key element [element ...]
# 示例:向消息队列尾部添加消息
RPUSH message:queue "message3"

# 移除并返回列表头部元素
LPOP key
# 示例:从消息队列头部取出消息
LPOP message:queue

# 移除并返回列表尾部元素
RPOP key
# 示例:从消息队列尾部取出消息
RPOP message:queue

# 返回列表指定范围内的元素
LRANGE key start stop
# 示例:获取消息队列的前5条消息
LRANGE message:queue 0 4

# 获取列表长度
LLEN key
# 示例:获取消息队列中的消息数量
LLEN message:queue

# 在列表中某个元素之前或之后插入元素
LINSERT key BEFORE|AFTER pivot element
# 示例:在指定消息后插入新消息
LINSERT message:queue AFTER "message2" "message2.5"

# 通过索引获取列表中的元素
LINDEX key index
# 示例:获取消息队列的第3条消息(索引从0开始)
LINDEX message:queue 2

# 通过索引设置列表中元素的值
LSET key index element
# 示例:修改消息队列的第2条消息
LSET message:queue 1 "updated_message"

# 移除列表中指定数量的指定元素
LREM key count element
# 示例:移除消息队列中所有的 "message1"
LREM message:queue 0 "message1"
# 示例:移除消息队列中前2个 "message2"
LREM message:queue 2 "message2"

# 修剪列表,只保留指定区间内的元素
LTRIM key start stop
# 示例:只保留消息队列的前10条消息
LTRIM message:queue 0 9

应用场景

  • 消息队列
  • 最新内容展示
  • 任务队列
  • 用户时间线

三、集合 (Set)

Redis 集合是无序的、唯一的字符串集合,不允许重复元素,底层实现是哈希表。

基本操作命令

# 向集合添加一个或多个元素
SADD key member [member ...]
# 示例:添加用户1001的兴趣标签
SADD user:1001:tags "sports" "music" "reading"

# 判断元素是否在集合中
SISMEMBER key member
# 示例:检查用户1001是否有 "sports" 标签
SISMEMBER user:1001:tags "sports"

# 获取集合中的所有元素
SMEMBERS key
# 示例:获取用户1001的所有兴趣标签
SMEMBERS user:1001:tags

# 获取集合的大小
SCARD key
# 示例:获取用户1001的兴趣标签数量
SCARD user:1001:tags

# 移除集合中的一个或多个元素
SREM key member [member ...]
# 示例:移除用户1001的 "music" 标签
SREM user:1001:tags "music"

# 随机移除并返回集合中的一个元素
SPOP key
# 示例:随机抽取一个兴趣标签
SPOP user:1001:tags

# 随机返回集合中的一个或多个元素,但不移除
SRANDMEMBER key [count]
# 示例:随机返回2个兴趣标签
SRANDMEMBER user:1001:tags 2

# 集合交集
SINTER key1 [key2 ...]
# 示例:获取用户1001和用户1002共同的兴趣标签
SINTER user:1001:tags user:1002:tags

# 集合并集
SUNION key1 [key2 ...]
# 示例:获取用户1001和用户1002的所有兴趣标签
SUNION user:1001:tags user:1002:tags

# 集合差集
SDIFF key1 [key2 ...]
# 示例:获取用户1001有但用户1002没有的兴趣标签
SDIFF user:1001:tags user:1002:tags

# 将集合的交集存储到新集合
SINTERSTORE destination key1 [key2 ...]
# 示例:存储用户1001和用户1002的共同兴趣标签到新集合
SINTERSTORE user:common:tags user:1001:tags user:1002:tags

应用场景

  • 标签系统
  • 用户关系(关注、粉丝)
  • 随机推荐
  • 数据去重

四、有序集合 (Sorted Set)

有序集合是 Redis 最强大的数据类型之一,它结合了集合和列表的特性,元素唯一且有序,每个元素都关联一个分数用于排序。

基本操作命令

# 向有序集合添加一个或多个元素,或者更新已存在元素的分数
ZADD key [NX|XX] [CH] [INCR] score member [score member ...]
# 示例:添加用户到排行榜
ZADD leaderboard 100 "user1001" 200 "user1002" 150 "user1003"

# 获取有序集合中指定范围的元素(按分数从小到大)
ZRANGE key start stop [WITHSCORES]
# 示例:获取排行榜前3名(带分数)
ZRANGE leaderboard 0 2 WITHSCORES

# 获取有序集合中指定范围的元素(按分数从大到小)
ZREVRANGE key start stop [WITHSCORES]
# 示例:获取排行榜倒数3名(带分数)
ZREVRANGE leaderboard 0 2 WITHSCORES

# 获取有序集合中分数在指定区间内的元素
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
# 示例:获取分数在100-200之间的用户(带分数)
ZRANGEBYSCORE leaderboard 100 200 WITHSCORES

# 获取有序集合的大小
ZCARD key
# 示例:获取排行榜中的用户数量
ZCARD leaderboard

# 获取有序集合中分数在指定区间内的元素数量
ZCOUNT key min max
# 示例:获取分数在100-150之间的用户数量
ZCOUNT leaderboard 100 150

# 获取有序集合中指定元素的分数
ZSCORE key member
# 示例:获取用户1001的分数
ZSCORE leaderboard "user1001"

# 增加有序集合中指定元素的分数
ZINCRBY key increment member
# 示例:给用户1001的分数增加50
ZINCRBY leaderboard 50 "user1001"

# 移除有序集合中的一个或多个元素
ZREM key member [member ...]
# 示例:从排行榜中移除用户1002
ZREM leaderboard "user1002"

# 获取有序集合中指定元素的排名(按分数从小到大,从0开始)
ZRANK key member
# 示例:获取用户1003的排名
ZRANK leaderboard "user1003"

# 获取有序集合中指定元素的排名(按分数从大到小,从0开始)
ZREVRANK key member
# 示例:获取用户1003的逆序排名
ZREVRANK leaderboard "user1003"

# 移除有序集合中指定排名范围内的元素
ZREMRANGEBYRANK key start stop
# 示例:移除排行榜中排名最后的2个用户
ZREMRANGEBYRANK leaderboard -2 -1

# 移除有序集合中分数在指定区间内的元素
ZREMRANGEBYSCORE key min max
# 示例:移除排行榜中分数小于100的用户
ZREMRANGEBYSCORE leaderboard -inf 100

应用场景

  • 排行榜系统
  • 带权重的消息队列
  • 时间序列数据
  • 优先级任务调度

五、哈希 (Hash)

Redis 哈希是一个键值对集合,适合存储对象,可以看作是字段和值的映射表。

基本操作命令

# 设置哈希表字段的值
HSET key field value
# 示例:设置用户1001的信息
HSET user:1001 name "zhangsan" age 25

# 获取哈希表字段的值
HGET key field
# 示例:获取用户1001的姓名
HGET user:1001 name

# 设置多个哈希表字段的值
HMSET key field1 value1 field2 value2 ...
# 示例:一次设置用户1001的多个信息
HMSET user:1001 name "zhangsan" age 25 city "beijing"

# 获取多个哈希表字段的值
HMGET key field1 field2 ...
# 示例:一次获取用户1001的多个信息
HMGET user:1001 name age city

# 获取哈希表中所有字段和值
HGETALL key
# 示例:获取用户1001的所有信息
HGETALL user:1001

# 获取哈希表中的字段数量
HLEN key
# 示例:获取用户1001的信息字段数量
HLEN user:1001

# 判断哈希表中是否存在指定字段
HEXISTS key field
# 示例:检查用户1001是否有邮箱字段
HEXISTS user:1001 email

# 删除哈希表中的一个或多个字段
HDEL key field [field ...]
# 示例:删除用户1001的年龄字段
HDEL user:1001 age

# 获取哈希表中的所有字段名
HKEYS key
# 示例:获取用户1001的所有字段名
HKEYS user:1001

# 获取哈希表中的所有字段值
HVALS key
# 示例:获取用户1001的所有字段值
HVALS user:1001

# 为哈希表中指定字段的值增加一个整数
HINCRBY key field increment
# 示例:为用户1001的年龄增加1
HINCRBY user:1001 age 1

# 为哈希表中指定字段的值增加一个浮点数
HINCRBYFLOAT key field increment
# 示例:为用户1001的余额增加10.5
HINCRBYFLOAT user:1001 balance 10.5

# 仅当字段不存在时设置值
HSETNX key field value
# 示例:设置用户1001的注册时间(仅当不存在时)
HSETNX user:1001 register_time "2023-01-01"

应用场景

  • 存储用户信息
  • 产品信息管理
  • 配置信息存储
  • 购物车实现

六、位图 (Bitmap)

位图是特殊的字符串,通过位操作实现高效的位级别的数据存储和查询。

基本操作命令

# 设置位图中指定偏移量的值(0或1)
SETBIT key offset value
# 示例:记录用户1001在2023年1月1日的登录状态(1表示登录)
SETBIT user:1001:login:2023 0 1
# 示例:记录用户1001在2023年1月3日的登录状态
SETBIT user:1001:login:2023 2 1

# 获取位图中指定偏移量的值
GETBIT key offset
# 示例:查询用户1001在2023年1月1日的登录状态
GETBIT user:1001:login:2023 0

# 统计位图中值为1的位的数量
BITCOUNT key [start end]
# 示例:统计用户1001在2023年1月份的登录天数
BITCOUNT user:1001:login:2023 0 30

# 对一个或多个位图执行位运算,并将结果存储到目标键
BITOP operation destkey key [key ...]
# 示例:计算多个用户在同一天的共同登录状态
BITOP AND common:login:day0 user:1001:login:2023 user:1002:login:2023
# 示例:计算多个用户在同一天的总登录状态
BITOP OR total:login:day0 user:1001:login:2023 user:1002:login:2023

# 查找位图中第一个值为0或1的位的位置
BITPOS key bit [start] [end]
# 示例:查找用户1001在2023年第一个未登录的日期
BITPOS user:1001:login:2023 0

应用场景

  • 用户签到系统
  • 在线状态表示
  • 布隆过滤器实现
  • 权限控制

七、HyperLogLog

HyperLogLog 是一种概率数据结构,用于近似计算集合的基数(元素数量),占用空间小且效率高。

基本操作命令

# 添加元素到 HyperLogLog
PFADD key element [element ...]
# 示例:记录网站访问的用户ID
PFADD website:visitors user1001 user1002 user1003

# 获取 HyperLogLog 的近似基数
PFCOUNT key [key ...]
# 示例:统计网站的独立访客数
PFCOUNT website:visitors
# 示例:合并统计多个网站的独立访客数
PFCOUNT website:visitors1 website:visitors2

# 合并多个 HyperLogLog 到一个新的 HyperLogLog
PFMERGE destkey sourcekey [sourcekey ...]
# 示例:合并两天的访问数据
PFMERGE website:visitors:20230101_20230102 website:visitors:20230101 website:visitors:20230102

应用场景

  • 网站UV统计
  • 大型数据集基数估算
  • 电商平台商品浏览量统计

八、地理位置 (Geo)

Redis 提供了地理位置相关功能,可以存储地理位置坐标,并支持距离计算等操作。

基本操作命令

# 添加地理位置信息
GEOADD key longitude latitude member [longitude latitude member ...]
# 示例:添加几个城市的地理位置
GEOADD cities 116.405285 39.904989 "beijing" 121.472644 31.231706 "shanghai"

# 获取地理位置的坐标
GEOPOS key member [member ...]
# 示例:获取北京的经纬度
GEOPOS cities "beijing"

# 计算两个位置之间的距离
GEODIST key member1 member2 [unit]
# 示例:计算北京到上海的距离(公里)
GEODIST cities "beijing" "shanghai" km

# 根据指定位置和半径,获取范围内的地理位置
GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC]
# 示例:获取北京周边100公里内的城市(带距离)
GEORADIUS cities 116.405285 39.904989 100 km WITHDIST

# 根据指定成员和半径,获取范围内的地理位置
GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC]
# 示例:获取北京周边100公里内的城市(带距离)
GEORADIUSBYMEMBER cities "beijing" 100 km WITHDIST

# 获取地理位置的哈希值
GEOHASH key member [member ...]
# 示例:获取北京的地理位置哈希值
GEOHASH cities "beijing"

# 删除地理位置信息
ZREM key member [member ...]
# 示例:删除北京的地理位置信息
ZREM cities "beijing"

应用场景

  • 附近的人功能
  • 地理位置推荐
  • 地图距离计算
  • 位置签到功能

九、通用命令

以下是适用于所有数据类型的通用命令:

# 删除键
DEL key [key ...]
# 示例:删除用户1001的所有信息
DEL user:1001 user:1001:name user:1001:age

# 检查键是否存在
EXISTS key [key ...]
# 示例:检查用户1001的信息是否存在
EXISTS user:1001

# 设置键的过期时间(秒)
EXPIRE key seconds
# 示例:设置用户会话5分钟后过期
EXPIRE session:user1001 300

# 设置键的过期时间(毫秒)
PEXPIRE key milliseconds
# 示例:设置用户会话5000毫秒后过期
PEXPIRE session:user1001 5000

# 设置键在指定时间点过期
EXPIREAT key timestamp
# 示例:设置用户会话在2023-01-01 00:00:00过期
EXPIREAT session:user1001 1672531200

# 获取键的剩余过期时间(秒)
TTL key
# 示例:获取用户会话的剩余有效时间
TTL session:user1001

# 获取键的剩余过期时间(毫秒)
PTTL key
# 示例:获取用户会话的剩余有效时间(毫秒)
PTTL session:user1001

# 移除键的过期时间
PERSIST key
# 示例:移除用户会话的过期时间
PERSIST session:user1001

# 重命名键
RENAME key newkey
# 示例:重命名用户会话键
RENAME session:user1001 session:user1001:old

# 仅当新键不存在时重命名
RENAMENX key newkey
# 示例:安全地重命名用户会话键
RENAMENX session:user1001 session:user1001:new

# 获取键的类型
TYPE key
# 示例:获取用户信息的类型
TYPE user:1001

# 查找符合模式的键
KEYS pattern
# 示例:查找所有用户信息键
KEYS user:*

# 随机返回一个键
RANDOMKEY

# 清空当前数据库
FLUSHDB

# 清空所有数据库
FLUSHALL

十、总结

Redis 支持丰富的数据类型,每种类型都有其特定的应用场景和操作命令。以下是各数据类型的主要特点和适用场景总结:

数据类型 特点 适用场景
字符串 (String) 二进制安全,存储任意数据 缓存、计数器、分布式锁
列表 (List) 有序,可重复,双向链表实现 消息队列、最新内容展示
集合 (Set) 无序,唯一,支持交集并集差集 标签系统、用户关系、数据去重
有序集合 (Sorted Set) 有序,唯一,带分数,支持范围查询 排行榜、带权重的队列、优先级任务
哈希 (Hash) 键值对集合,适合存储对象 用户信息、产品信息、配置管理
位图 (Bitmap) 位级操作,节省空间 签到系统、在线状态、权限控制
HyperLogLog 概率数据结构,近似基数统计 UV统计、大型数据集估算
地理位置 (Geo) 存储地理位置,支持距离计算 附近的人、位置推荐、地图功能

通过合理选择和使用这些数据类型,可以充分发挥 Redis 的高性能特性,构建高效、可扩展的应用系统。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐