📝 引言

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

在当今这个数据如洪水般涌来的时代,如何高效地存储和操作数据,几乎成了每个开发者的"必修课"。而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、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐