一、Redis数据类型概述
Redis支持五种核心数据结构,每种结构都针对特定场景优化:
| 数据类型 | 存储结构 | 主要应用场景 | 时间复杂度 |
|---|---|---|---|
| String | 简单动态字符串(SDS) | 缓存、计数器、分布式锁 | O(1) |
| Hash | 键值对集合 | 对象存储、购物车、用户属性 | O(1) |
| List | 双向链表 | 消息队列、最新列表、关注列表 | 头尾操作O(1) |
| Set | 无序集合 | 标签、共同好友、随机推荐 | O(1) |
| Sorted Set | 有序集合 | 排行榜、延迟队列、范围查询 | O(logN) |
二、String(字符串类型)
核心特性
java
// Redis底层使用SDS(简单动态字符串)
struct sdshdr {
unsigned int len; // 字符串长度
unsigned int free; // 未使用字节数
char buf[]; // 字节数组
};
二进制安全:可存储任何二进制数据,包括图片、序列化对象等。
常用命令
bash
# 基本操作
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 # 毫秒级过期
Java示例
java
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<String> values = jedis.mget("user:1:name", "user:1:age");
三、Hash(哈希类型)
适用场景
存储对象,如用户信息、商品详情。相比JSON字符串存储,可独立更新单个字段。
常用命令
bash
# 字段操作
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 # 数值字段增加
商品信息存储示例
bash
# 商品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 # 获取完整信息
Java示例
java
// 存储用户信息
Map<String, String> 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<String> fields = jedis.hmget("user:1001", "name", "age");
Map<String, String> allFields = jedis.hgetAll("user:1001");
// 字段操作
jedis.hincrBy("user:1001", "age", 1); // 年龄+1
jedis.hdel("user:1001", "sex"); // 删除字段
四、List(列表类型)
数据结构
基于双向链表实现,两端操作O(1),中间操作O(n)。
常用命令
bash
# 增加元素
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" # 设置指定索引值
商品评论系统示例
bash
# 商品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
Java示例
java
// 消息队列实现
jedis.lpush("messages", "Hello");
jedis.lpush("messages", "World");
jedis.rpush("messages", "!");
// 获取所有消息
List<String> 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(集合类型)
特性
无序、唯一元素,基于哈希表实现,操作O(1)。
常用命令
bash
# 基本操作
SADD tags java redis python # 添加元素
SMEMBERS tags # 获取所有元素
SREM tags python # 删除元素
SISMEMBER tags java # 判断是否存在
# 集合运算
SINTER set1 set2 # 交集
SUNION set1 set2 # 并集
SDIFF set1 set2 # 差集(set1有set2无)
SCARD tags # 元素个数
SPOP tags # 随机弹出一个
SRANDMEMBER tags 2 # 随机获取2个(不删除)
社交应用示例
bash
# 用户标签
SADD user:1001:tags 音乐 电影 编程
SADD user:1002:tags 电影 游戏 摄影
# 共同兴趣
SINTER user:1001:tags user:1002:tags
# 返回: 电影
# 推荐标签(你有我无的)
SDIFF user:1002:tags user:1001:tags
# 返回: 游戏 摄影
六、Sorted Set(有序集合)
特性
元素唯一,每个元素关联一个分数(score),按分数排序。
常用命令
bash
# 添加元素
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 # 元素总数
排行榜实现
bash
# 游戏积分榜
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
Java示例
java
// 黑客排名(按出生年份)
jedis.zadd("hackers", 1940, "Alan Kay");
jedis.zadd("hackers", 1953, "Richard Stallman");
// 按分数升序获取
Set<String> asc = jedis.zrange("hackers", 0, -1);
// 按分数降序获取
Set<String> desc = jedis.zrevrange("hackers", 0, -1);
// 分数范围查询
Set<String> range = jedis.zrangeByScore("hackers", 1950, 1970);
七、键管理命令
常用键操作
bash
# 键查询
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 # 指定时间戳过期
批量操作示例
bash
# 批量设置带过期
MSET k1 v1 k2 v2
EXPIRE k1 3600
EXPIRE k2 3600
# 扫描所有键(代替KEYS,不阻塞)
SCAN 0 MATCH user:* COUNT 10
八、服务器管理命令
bash
# 连接测试
PING # 返回PONG表示正常
ECHO "hello" # 回显字符串
# 数据库操作
SELECT 1 # 切换到1号库(0-15)
DBSIZE # 当前库键数量
FLUSHDB # 清空当前库
FLUSHALL # 清空所有库
# 服务器信息
INFO # 详细服务器信息
INFO memory # 内存信息
INFO stats # 统计信息
CLIENT LIST # 客户端列表
TIME # 服务器时间
# 持久化
SAVE # 同步保存(阻塞)
BGSAVE # 后台保存
LASTSAVE # 上次保存时间