游乐游手机版
首页/数据库/文章详情

Redis五种核心数据类型及命令示例

时间:2026-06-14 07:04
一、Redis数据类型概述 Redis提供了五种核心数据结构,每种都是为特定使用场景量身定做的。理解它们的区别和适用场景,是高效使用Redis的前提。 数据类型 存储结构 主要应用场景 时间复杂度 String​ 简单动态字符串(SDS) 缓存、计数器、分布式锁 O(1) Hash​ 键值对集合 对

一、Redis数据类型概述

Redis提供了五种核心数据结构,每种都是为特定使用场景量身定做的。理解它们的区别和适用场景,是高效使用Redis的前提。

Redis五种核心数据类型与命令示例

数据类型

存储结构

主要应用场景

时间复杂度

String

简单动态字符串(SDS)

缓存、计数器、分布式锁

O(1)

Hash

键值对集合

对象存储、购物车、用户属性

O(1)

List

双向链表

消息队列、最新列表、关注列表

头尾操作O(1)

Set

无序集合

标签、共同好友、随机推荐

O(1)

Sorted Set

有序集合

排行榜、延迟队列、范围查询

O(logN)

二、String(字符串类型)

核心特性

在底层,Redis的String类型并不是C语言那种简单的字符数组,而是用了一套叫SDS(简单动态字符串)的结构。这套结构让String具备了动态扩容、二进制安全等优势——你可以放字符串、数字、甚至是序列化对象,没问题。

// Redis底层使用SDS(简单动态字符串)struct sdshdr {
    unsigned int len;    // 字符串长度
    unsigned int free;   // 未使用字节数
    char buf[];         // 字节数组
};

二进制安全:这意味着你可以保存任何二进制数据,比如图片、序列化对象等,Redis不会对数据做任何截断或修改。

常用命令

# 基本操作
SET key value        # 设置键值
GET key             # 获取值
APPEND key value    # 追加值
STRLEN key          # 获取长度

# 批量操作
MSET k1 v1 k2 v2     # 批量设置
MGET k1 k2          # 批量获取

# 数值操作
INCR key            # 自增1
INCRBY key 5        # 增加指定数值
DECR key            # 自减1
SETNX key value     # 不存在时设置(实现分布式锁基础)

# 过期时间
SETEX key 10 value  # 设置值并指定10秒过期
SET key value EX 10 # 同上
PSETEX key 1000 value # 毫秒级过期

Ja va示例

Jedis jedis = new Jedis("localhost");

// 基本操作
jedis.set("username", "minxr");
String name = jedis.get("username");

// 追加操作
jedis.append("username", "jintao");

// 设置过期
jedis.setex("session_token", 3600, "abc123");

// 批量操作
jedis.mset("user:1:name", "Alice", "user:1:age", "25");
List values = jedis.mget("user:1:name", "user:1:age");

三、Hash(哈希类型)

适用场景

Hash类型用来存储对象再合适不过了,比如用户信息、商品详情。和直接存一个完整的JSON字符串相比,它的好处是你可以独立更新单个字段,而不需要把整个对象读出来再写回去。

常用命令

# 字段操作
HSET user:1001 name "张三" age 25  # 设置字段
HGET user:1001 name              # 获取字段
HMSET user:1001 email "a@b.com" phone "13800138000"  # 批量设置
HMGET user:1001 name age         # 批量获取
HGETALL user:1001               # 获取所有字段
HDEL user:1001 email            # 删除字段

# 判断与计数
HEXISTS user:1001 name          # 检查字段是否存在
HLEN user:1001                  # 字段数量
HSETNX user:1001 name "李四"    # 字段不存在时设置

# 获取键/值
HKEYS user:1001                 # 所有字段名
HVALS user:1001                 # 所有字段值
HINCRBY user:1001 score 10      # 数值字段增加

商品信息存储示例

# 商品ID为1001的信息
HMSET items:1001 id 1001 name "iPhone" price 5999.00 stock 100
HGET items:1001 name          # 获取商品名
HINCRBY items:1001 stock -1   # 减少库存
HGETALL items:1001            # 获取完整信息

Ja va示例

// 存储用户信息
Map user = new HashMap<>();
user.put("name", "Akshi");
user.put("age", "2");
user.put("sex", "Female");
jedis.hmset("user:1001", user);

// 获取操作
String name = jedis.hget("user:1001", "name");
List fields = jedis.hmget("user:1001", "name", "age");
Map allFields = jedis.hgetAll("user:1001");

// 字段操作
jedis.hincrBy("user:1001", "age", 1);  // 年龄+1
jedis.hdel("user:1001", "sex");        // 删除字段

四、List(列表类型)

数据结构

List底层是双向链表,这意味着在头尾两端操作都是O(1)级别,但如果在中间插入或查询,那复杂度就是O(n)了。所以它的主要用武之地在消息队列、最新动态列表这些场景。

常用命令

# 增加元素
LPUSH list:1 a b c    # 左侧插入
RPUSH list:1 d e f    # 右侧插入
LINSERT list:1 BEFORE b x  # 指定位置插入

# 弹出元素
LPOP list:1          # 左侧弹出
RPOP list:1          # 右侧弹出
RPOPLPUSH list:1 list:2  # 原子移动

# 查询操作
LRANGE list:1 0 2     # 获取片段(包含两端)
LINDEX list:1 2       # 获取指定索引元素
LLEN list:1          # 列表长度

# 删除操作
LREM list:1 2 "a"    # 删除前2个"a"
LTRIM list:1 0 3     # 只保留0-3索引元素
LSET list:1 0 "new"  # 设置指定索引值

商品评论系统示例

# 商品1001的评论列表
LPUSH items:comment:1001 '{"id":1,"content":"商品不错","time":1630295077289}'
LPUSH items:comment:1001 '{"id":2,"content":"物流很快","time":1630295077290}'
# 获取最新10条评论
LRANGE items:comment:1001 0 9

Ja va示例

// 消息队列实现
jedis.lpush("messages", "Hello");
jedis.lpush("messages", "World");
jedis.rpush("messages", "!");

// 获取所有消息
List messages = jedis.lrange("messages", 0, -1);

// 阻塞式弹出(实现任务队列)
String task = jedis.brpop(5, "task_queue");  // 最多等待5秒

// 最新动态列表
jedis.lpush("news:latest", "新闻1", "新闻2", "新闻3");
jedis.ltrim("news:latest", 0, 9);  // 只保留最新10条

五、Set(集合类型)

特性

Set的特点:无序、元素唯一。实现原理是哈希表,所以操作复杂度是O(1)。它的价值主要体现在集合运算上——交集、并集、差集,对于做标签系统、共同好友这些功能来说,简直是神器。

常用命令

# 基本操作
SADD tags ja va redis python  # 添加元素
SMEMBERS tags               # 获取所有元素
SREM tags python           # 删除元素
SISMEMBER tags ja va        # 判断是否存在

# 集合运算
SINTER set1 set2           # 交集
SUNION set1 set2           # 并集
SDIFF set1 set2            # 差集(set1有set2无)

SCARD tags                 # 元素个数
SPOP tags                  # 随机弹出一个
SRANDMEMBER tags 2         # 随机获取2个(不删除)

社交应用示例

# 用户标签
SADD user:1001:tags 音乐 电影 编程
SADD user:1002:tags 电影 游戏 摄影

# 共同兴趣
SINTER user:1001:tags user:1002:tags
# 返回: 电影

# 推荐标签(你有我无的)
SDIFF user:1002:tags user:1001:tags
# 返回: 游戏 摄影

六、Sorted Set(有序集合)

特性

和Set类似,元素也是唯一的,但每个元素都关联了一个分数(score)。Redis会根据这个分数进行排序,这让它成为实现排行榜的天然选择。另外,延迟队列、范围查询这些场景也少不了它。

常用命令

# 添加元素
ZADD rank 95 "张三" 89 "李四" 78 "王五"
ZADD rank 97 "李四"  # 更新分数

# 查询操作
ZRANGE rank 0 2              # 升序前3名
ZREVRANGE rank 0 2           # 降序前3名
ZRANGE rank 0 2 WITHSCORES   # 带分数
ZSCORE rank "张三"          # 获取分数
ZRANK rank "张三"           # 升序排名
ZREVRANK rank "张三"        # 降序排名

# 分数范围操作
ZRANGEBYSCORE rank 90 100   # 90-100分
ZCOUNT rank 80 90           # 80-90分人数
ZINCRBY rank 5 "张三"        # 增加5分

# 删除操作
ZREM rank "王五"            # 删除元素
ZREMRANGEBYRANK rank 0 2    # 删除排名0-2
ZREMRANGEBYSCORE rank 0 60  # 删除0-60分
ZCARD rank                  # 元素总数

排行榜实现

# 游戏积分榜
ZADD game:rank 1500 "玩家A" 1200 "玩家B" 1800 "玩家C"

# 获取前十名
ZREVRANGE game:rank 0 9 WITHSCORES

# 增加积分
ZINCRBY game:rank 100 "玩家B"

# 查询我的排名(从0开始)
ZREVRANK game:rank "玩家A"

# 查询分数段人数
ZCOUNT game:rank 1000 2000

Ja va示例

// 黑客排名(按出生年份)
jedis.zadd("hackers", 1940, "Alan Kay");
jedis.zadd("hackers", 1953, "Richard Stallman");

// 按分数升序获取
Set asc = jedis.zrange("hackers", 0, -1);

// 按分数降序获取
Set desc = jedis.zrevrange("hackers", 0, -1);

// 分数范围查询
Set range = jedis.zrangeByScore("hackers", 1950, 1970);

七、键管理命令

常用键操作

在实际应用中,键的管理和查询是日常操作的重点——比如查找特定模式的键,或者设置过期时间。

# 键查询
KEYS user:*           # 匹配user:开头的键
EXISTS key           # 键是否存在
TYPE key             # 键的数据类型
DEL key1 key2       # 删除键
UNLINK key          # 非阻塞删除(Redis 4.0+)

# 重命名
RENAME old new      # 重命名
RENAMENX old new    # 新名不存在时才重命名

# 过期时间
EXPIRE key 60       # 60秒后过期
TTL key             # 查看剩余时间(秒)
PTTL key            # 剩余毫秒数
PERSIST key         # 移除过期时间
EXPIREAT key 1630345600  # 指定时间戳过期

批量操作示例

# 批量设置带过期
MSET k1 v1 k2 v2
EXPIRE k1 3600
EXPIRE k2 3600

# 扫描所有键(代替KEYS,不阻塞)
SCAN 0 MATCH user:* COUNT 10

八、服务器管理命令

# 连接测试
PING          # 返回PONG表示正常
ECHO "hello"  # 回显字符串

# 数据库操作
SELECT 1      # 切换到1号库(0-15)
DBSIZE        # 当前库键数量
FLUSHDB       # 清空当前库
FLUSHALL      # 清空所有库

# 服务器信息
INFO          # 详细服务器信息
INFO memory   # 内存信息
INFO stats    # 统计信息
CLIENT LIST   # 客户端列表
TIME          # 服务器时间

# 持久化
SA VE          # 同步保存(阻塞)
BGSA VE        # 后台保存
LASTSA VE     # 上次保存时间
来源:https://www.jb51.net/database/357603x4x.htm
上一篇Redis常用命令详解:基础、进阶与场景化实战案例 下一篇Redis布隆过滤器实现缓存去重实例详解
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
Redis 7.0增量AOF重写RDB前导码配置详解
数据库 · 2026-07-02

Redis 7.0增量AOF重写RDB前导码配置详解

先说一个几乎所有人都踩过的典型误区:很多人把 aof-use-rdb-preamble yes 当作开启“增量重写”的开关。实际上,这个配置只干了一件事——让重写后的 AOF 文件头部带上 RDB 快照。它解决的是加载速度问题,跟“增量重写”本身的概念压根不是一回事。真正的增量重写,依赖的是 Red

在Python Tornado异步框架中安全执行SQL命令的方法与最佳实践
数据库 · 2026-07-02

在Python Tornado异步框架中安全执行SQL命令的方法与最佳实践

直接在Tornado里用SQLAlchemy同步执行SQL,结果就是阻塞IOLoop,所谓“异步框架里写同步数据库代码”,等于白搭。安全执行的关键不是“怎么写SQL”,而是“怎么不卡住事件循环”。 为什么不能在RequestHandler里直接调用session execute() 因为sessio

利用SQL触发器实现在INSERT数据时自动同步到审计表
数据库 · 2026-07-02

利用SQL触发器实现在INSERT数据时自动同步到审计表

先说结论:可以用触发器把 INSERT 数据同步到审计表,但必须用 AFTER INSERT,并且审计表的字段顺序、类型、字符集得和源表严格一致。否则,轻则写入错位、数据截断,重则直接报错、丢数据。下面把这些坑一个一个掰开说。 能,但必须用 AFTER INSERT,且审计表字段顺序、类型、字符集要

如何用SQL编写按不同工作日统计员工出勤率
数据库 · 2026-07-02

如何用SQL编写按不同工作日统计员工出勤率

在实际业务中,统计不同工作日的出勤率是HR系统里的高频需求。如果直接按日期函数分组,很容易掉进语言环境、索引失效或分母口径的坑里。下面就来拆解具体的实现要点。 必须用 CASE WHEN 将日期映射为固定 weekday 标签(如 Mon )再分组,避免语言环境导致的分组断裂;需过滤 DOW IN

Spring Boot 3动态拼接SQL为何引发严重安全漏洞
数据库 · 2026-07-02

Spring Boot 3动态拼接SQL为何引发严重安全漏洞

SQL注入漏洞的核心成因,本质上是因为用户输入直接参与了SQL语句的字符串拼接,而未采用参数化绑定机制。在MyBatis中使用${}、QueryWrapper中调用apply()与last()、JPA的@Query注解进行拼接等操作,都会绕过PreparedStatement的安全防护。动态字段必须