Redis 的所有数据都是以 key-value(键值对)的形式存储的,我们所说的数据类型指的是 value 的数据类型。key 永远都是一个字符串(String)。
0、通用命令
keys: 查看当前库所有key (匹配:keys *1)
exists key: 判断某个key是否存在
type key: 查看你的key是什么类型
del key: 删除指定的key数据
expire key 10: 10秒钟:为给定的key设置过期时间
ttl key: 查看还有多少秒过期,-1表示永不过期,-2表示已过期
select: 命令切换数据库
dbsize: 查看当前数据库的key的数量
flushdb: 清空当前库
**flushall:**清空全部库
1、String(字符串)
String是Redis最基础的数据类型,可存储字符串、数字和二进制数据(如图片),单个值最大512MB 。对于整数和浮点数类型,可以直接执行原子性的自增/自减操作。
数据结构: 简单动态字符串(Simple Dynamic String,缩写SDS)。是可以修改的字符串,内部结构实现上类似于Java的ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配
常用命令示例
bash
# 基础操作
127.0.0.1:6379> SET user:name "Alice" # 设置键值对
OK
127.0.0.1:6379> GET user:name # 获取值
"Alice"
127.0.0.1:6379> DEL user:name # 删除键
(integer) 1
127.0.0.1:6379> GET user:name
(nil)
# 数字操作(原子性)
127.0.0.1:6379> SET article:100:views 0
OK
127.0.0.1:6379> INCR article:100:views # 自增1
(integer) 1
127.0.0.1:6379> INCRBY article:100:views 10 # 增加10
(integer) 11
127.0.0.1:6379> DECR article:100:views # 自减1
(integer) 10
# 批量操作(节省网络开销)
127.0.0.1:6379> MSET user:1:name "Bob" user:1:email "bob@example.com"
OK
127.0.0.1:6379> MGET user:1:name user:1:email
1) "Bob"
2) "bob@example.com"
# 设置过期时间(常用于缓存)
127.0.0.1:6379> SET session:xyz123 "user_data" EX 3600 # 3600秒后自动过期
OK
# 不存在时设置(分布式锁常用)
127.0.0.1:6379> SETNX lock:order 1 # 成功返回 1,失败返回 0
应用场景
- 缓存:存储数据库查询结果
- 计数器:网站访问量、点赞数
- 会话存储:用户登录令牌
- 分布式锁:使用 SETNX 实现
2、Hash(哈希)
Hash 是一个键值对集合,适合存储对象。每个 Hash 可以存储 2³² - 1 个字段-值对。
数据结构: ziplist(压缩列表 ),hashtable(哈希表)。当field-value长度较短且个数较少时,使用ziplist,否则使用hashtable。
常用命令示例
bash
# 存储一个用户对象
127.0.0.1:6379> HSET user:1000 name "Alice" age 30 email "alice@example.org" # 设置多个field
(integer) 3
127.0.0.1:6379> HGET user:1000 name # 获取一个field的值
"Alice"
127.0.0.1:6379> HGETALL user:1000 # 获取整个哈希
1) "name"
2) "Alice"
3) "age"
4) "30"
5) "email"
6) "alice@example.org"
127.0.0.1:6379> HKEYS user:1000 # 获取所有field名
1) "name"
2) "age"
3) "email"
127.0.0.1:6379> HVALS user:1000 # 获取所有value
1) "Alice"
2) "30"
3) "alice@example.org"
# 批量获取字段
127.0.0.1:6379> HMGET user:1001 name age # ["Alice", "30"]
# 统计字段数量
127.0.0.1:6379> HLEN user:1001 # 2
# 单独操作某个field
127.0.0.1:6379> HINCRBY user:1000 age 1 # 给age字段的值增加1
(integer) 31
127.0.0.1:6379> HSET user:1000 age 32 # 直接设置age字段
(integer) 0
127.0.0.1:6379> HDEL user:1000 email # 删除email字段
(integer) 1
应用场景
- 对象存储:用户信息、商品信息
- 购物车:用户ID为键,商品ID为字段,数量为值
- 配置存储:系统配置项
3、List(列表)
List 是简单的字符串列表,按照插入顺序排序。元素可以重复。可以从头部或尾部添加元素。
它的底层实际是个双向链表,对两端的操作性能很高,通过索引下标的操作中间的节点性能会较差。
常用命令示例
bash
# 像一个队列(FIFO:先进先出)
127.0.0.1:6379> LPUSH orders:queue "order1001" # 从左边插入
(integer) 1
127.0.0.1:6379> LPUSH orders:queue "order1002"
(integer) 2
127.0.0.1:6379> RPOP orders:queue # 从右边取出,得到最早进入的"order1001"
"order1001"
127.0.0.1:6379> RPOP orders:queue # 取出"order1002"
"order1002"
# 像一个栈(LIFO:后进先出)
127.0.0.1:6379> LPUSH my:stack "task1"
127.0.0.1:6379> LPUSH my:stack "task2"
127.0.0.1:6379> LPOP my:stack # 从左边取出,得到最后进入的"task2"
"task2"
# 获取列表范围
127.0.0.1:6379> RPUSH news:latest "news_id_555" # 从右边插入,构建时间顺序列表
127.0.0.1:6379> RPUSH news:latest "news_id_556"
127.0.0.1:6379> RPUSH news:latest "news_id_557"
127.0.0.1:6379> LRANGE news:latest 0 2 # 获取前3个元素
1) "news_id_555"
2) "news_id_556"
3) "news_id_557"
127.0.0.1:6379> LRANGE news:latest 0 -1 # 获取所有元素,-1表示最后一个
1) "news_id_555"
2) "news_id_556"
3) "news_id_557"
典型场景
- 消息队列(LPUSH + BRPOP 实现生产者 - 消费者模型)
- 最新列表(如用户最新动态、商品评论)
- 栈(LPUSH + LPOP)和队列(LPUSH + RPOP)
4、Set(集合)
Set 是 String 类型的无序集合,元素唯一不重复,支持交集、并集、差集等操作
数据结构: 它底层其实是一个value为null 的hash表,所以添加,删除,查找的复杂度都是O(1)。
常用命令示例
bash
# 添加成员并自动去重
127.0.0.1:6379> SADD article:800:tags "tech" "redis" "database" "tech"
(integer) 3 # 返回成功添加的数量,重复的"tech"被忽略
127.0.0.1:6379> SMEMBERS article:800:tags # 获取集合所有成员(无序)
1) "database"
2) "redis"
3) "tech"
# 集合运算
127.0.0.1:6379> SADD user:alice:follows "user:ben" "user:charlie" "user:diana"
(integer) 3
127.0.0.1:6379> SADD user:bob:follows "user:alice" "user:diana" "user:evan"
(integer) 3
127.0.0.1:6379> SINTER user:alice:follows user:bob:follows # 交集:共同关注
1) "user:diana"
127.0.0.1:6379> SUNION user:alice:follows user:bob:follows # 并集:所有关注的人
1) "user:alice"
2) "user:ben"
3) "user:charlie"
4) "user:diana"
5) "user:evan"
127.0.0.1:6379> SISMEMBER user:alice:follows "user:ben" # 检查ben是否在alice的关注列表中
(integer) 1
# 随机元素(抽奖)
127.0.0.1:6379> SADD lottery:users "user1" "user2" "user3" "user4" "user5"
(integer) 5
127.0.0.1:6379> SRANDMEMBER lottery:users 2 # 随机抽取2个用户,不删除
1) "user3"
2) "user1"
127.0.0.1:6379> SPOP lottery:users 1 # 随机抽取1个用户,并从集合中删除(防止重复中奖)
1) "user2"
典型场景
- 去重存储(如用户浏览历史、点赞记录)
- 好友关系(共同好友、好友推荐)
- 标签系统(文章标签、商品分类)
- 随机推荐(抽奖)
5、ZSet (Sorted Set - 有序集合)
Sorted Set 类似 Set,但每个元素都关联一个分数(score),元素按分数从小到大排序。
数据结构:
- hash:hash的作用就是关联元素value和权重score,保障元素value的唯一性,可以通过元素value找到相应的score值。
- 跳跃表:跳跃表的目的在于给元素value排序,根据score的范围获取元素列表。
bash
# 添加成员和分数
127.0.0.1:6379> ZADD leaderboard 100 "player1" 85 "player2" 120 "player3"
(integer) 3
# 按分数升序获取(低到高,WITHSCORES选项会返回分数)
127.0.0.1:6379> ZRANGE leaderboard 0 -1 WITHSCORES
1) "player2"
2) "85"
3) "player1"
4) "100"
5) "player3"
6) "120"
# 按分数降序获取(高到低,获取Top 2)
127.0.0.1:6379> ZREVRANGE leaderboard 0 1 WITHSCORES
1) "player3"
2) "120"
3) "player1"
4) "100"
# 按分数范围查询
127.0.0.1:6379> ZRANGEBYSCORE leaderboard 90 110 WITHSCORES # 获取90<=score<=110的成员
1) "player1"
2) "100"
# 更新玩家分数(原子操作)
127.0.0.1:6379> ZINCRBY leaderboard 15 "player2" # 给player2加15分
"100"
127.0.0.1:6379> ZREVRANK leaderboard "player2" # 查看player2的排名(降序排名,0是第一名)
(integer) 1
典型场景
- 排行榜(用户积分、商品销量)
- 优先级队列(按分数排序任务)
- 范围查询(筛选分数在特定区间的元素)
6、总结
Redis 的五种核心数据类型各有其优势和应用场景:
- String:最简单灵活,适用于大多数简单场景
- Hash:适合存储对象,可以部分更新字段
- List:提供顺序存储,适合队列和堆栈场景
- Set:提供唯一性和集合运算,适合标签和社交关系
- Sorted Set:结合了Set和排序功能,适合排行榜和优先级队列