支持的数据类型
| 类型 | 描述 | 类似结构 |
|---|---|---|
| 字符串(String) | 二进制安全的字符串,可以存储文本、整数、浮点数甚至序列化后的对象。 | 最简单的键值对,类似一个变量。 |
| 哈希(Hash) | 键值对集合,适合存储对象(如用户信息、图书详情)。 | 类似于 MySQL 的一行记录,但字段可动态增减。 |
| 列表(List) | 字符串序列,按插入顺序排序。可在头部或尾部添加/弹出元素。 | 双向链表或数组。 |
| 集合(Set) | 无序且唯一的字符串集合。支持交集、并集、差集。 | 数学上的集合。 |
| 有序集合(Sorted Set) | 每个元素关联一个 分数(score),按分数排序,元素唯一。 | 排行榜、带权重的队列。 |
| 位图(Bitmap) | 本质是字符串,但可按位操作,节省空间。 | 布尔值数组。 |
| HyperLogLog | 概率性数据结构,用于统计唯一元素数量(基数计数),误差约0.81%。 | 近似去重计数。 |
| 地理空间(GEO) | 存储地理位置(经度、纬度),支持距离计算和范围查询。 | 地理位置索引。 |
工程中常用前5种,后3种在特定场景下很高效。
基本操作(命令示例)
以下命令均可在 redis-cli 中执行,或通过客户端库调用。
1. 字符串(String)
| 命令 | 功能 | 示例 |
|---|---|---|
SET key value | 设置键值 | SET book:1001 "Redis入门" |
GET key | 获取值 | GET book:1001 → "Redis入门" |
INCR key | 整数自增1(原子) | INCR borrow:count |
DECR key | 整数自减1 | DECR stock:1001 |
SETEX key seconds value | 设置键值并指定过期时间(秒) | SETEX session:abc 3600 "user123" |
MSET k1 v1 k2 v2 | 批量设置 | MSET a 1 b 2 c 3 |
MGET k1 k2 | 批量获取 | MGET a b → ["1","2"] |
示例:
> SET borrow:today 0
OK
> INCR borrow:today
(integer) 1
> INCR borrow:today
(integer) 2
> GET borrow:today
"2"2. 哈希(Hash)
| 命令 | 功能 | 示例 |
|---|---|---|
HSET key field value | 设置哈希中的字段 | HSET user:1001 name "张三" age 25 |
HGET key field | 获取哈希中的字段 | HGET user:1001 name → "张三" |
HGETALL key | 获取所有字段和值 | HGETALL user:1001 → 1) "name" 2) "张三" 3) "age" 4) "25" |
HINCRBY key field increment | 哈希字段整数自增 | HINCRBY user:1001 age 1 |
HDEL key field | 删除字段 | HDEL user:1001 age |
示例:
> HSET book:2001 title "Redis实战" author "王五" price 59
(integer) 3
> HGET book:2001 title
"Redis实战"
> HINCRBY book:2001 price 10
(integer) 693. 列表(List)
| 命令 | 功能 | 示例 |
|---|---|---|
LPUSH key value [value...] | 从左侧插入一个或多个元素 | LPUSH log "error1" "error2" |
RPUSH key value | 从右侧插入 | RPUSH queue "task1" |
LPOP key | 从左侧弹出元素 | LPOP log → "error2" |
RPOP key | 从右侧弹出 | RPOP queue |
LRANGE key start stop | 获取指定范围元素(0 -1 表示全部) | LRANGE log 0 -1 |
LLEN key | 获取列表长度 | LLEN queue |
示例:
> RPUSH messages "hello" "world" "!"
(integer) 3
> LRANGE messages 0 -1
1) "hello"
2) "world"
3) "!"
> LPOP messages
"hello"4. 集合(Set)
| 命令 | 功能 | 示例 |
|---|---|---|
SADD key member [member...] | 添加一个或多个成员(自动去重) | SADD tags "redis" "database" |
SMEMBERS key | 获取所有成员 | SMEMBERS tags |
SISMEMBER key member | 判断成员是否存在 | SISMEMBER tags "redis" → 1 |
SINTER key1 key2 | 求交集 | SINTER setA setB |
SUNION key1 key2 | 求并集 | SUNION setA setB |
SREM key member | 删除成员 | SREM tags "database" |
示例:
> SADD book:1001:tags "编程" "数据库" "NoSQL"
(integer) 3
> SADD book:1002:tags "编程" "Python"
(integer) 2
> SINTER book:1001:tags book:1002:tags
1) "编程"5. 有序集合(Sorted Set)
| 命令 | 功能 | 示例 |
|---|---|---|
ZADD key score member [score member...] | 添加元素及分数 | ZADD rank 100 "张三" 95 "李四" |
ZRANGE key start stop [WITHSCORES] | 按分数升序获取成员 | ZRANGE rank 0 -1 WITHSCORES |
ZREVRANGE key start stop | 按分数降序(排行榜) | ZREVRANGE rank 0 2 获取前三名 |
ZINCRBY key increment member | 增加成员的分数 | ZINCRBY rank 5 "张三" |
ZSCORE key member | 获取成员分数 | ZSCORE rank "张三" → "105" |
ZRANK key member | 获取排名(升序,从0开始) | ZRANK rank "李四" |
示例:
> ZADD borrow_rank 10 "book:1001" 23 "book:1002" 5 "book:1003"
(integer) 3
> ZREVRANGE borrow_rank 0 2 WITHSCORES
1) "book:1002"
2) "23"
3) "book:1001"
4) "10"
5) "book:1003"
6) "5"6. 通用键操作(所有类型通用)
| 命令 | 功能 | 示例 |
|---|---|---|
DEL key [key...] | 删除一个或多个键 | DEL book:1001 |
EXPIRE key seconds | 设置过期时间 | EXPIRE temp_data 60 |
TTL key | 查看剩余生存时间(秒,-1永久 -2不存在) | TTL session:abc |
KEYS pattern | 查找符合模式的键(生产环境慎用) | KEYS book:* |
TYPE key | 返回键的数据类型 | TYPE user:1001 → "hash" |
结合技术栈的编程示例
在图书管理系统中,Redis 作为高速缓存和计数器。以下展示 Python 负责原子操作(借书计数器更新排行榜),C++ 负责读取排行榜并缓存热门图书。
场景:用户借书时
- Python 脚本接收借书请求,更新 Redis 中的图书借阅次数(原子操作),同时向 SQLite 写入借阅记录。
- C++ 主程序读取 Redis 中的排行榜,并缓存热门图书详情。
Python 端(原子操作)
使用 redis-py 库。假设已经安装 redis。
import redis
# 连接 Redis(默认本地 6379)
r = redis.Redis(host='localhost', port=6379, decode_responses=True)
def on_borrow(book_id):
"""借书时调用:增加借阅计数,更新排行榜"""
# 原子操作:有序集合分数 +1
r.zincrby('borrow_rank', 1, f'book:{book_id}')
# 也可以增加一个当日计数器(字符串)
r.incr(f'borrow:today:{book_id}')
# 此处可以继续写 SQLite 持久化(省略)
print(f"Book {book_id} borrowed, rank updated.")
if __name__ == "__main__":
# 模拟用户借书
on_borrow('1001')
on_borrow('1002')
on_borrow('1001')C++ 端(读取排行榜,获取热门图书详情)
使用 hiredis 库(C 语言客户端,C++ 可封装)。示例代码片段:
#include <iostream>
#include <hiredis/hiredis.h>
int main() {
// 连接 Redis
redisContext *c = redisConnect("127.0.0.1", 6379);
if (c == nullptr || c->err) {
std::cerr << "Connection error" << std::endl;
return 1;
}
// 获取借阅排行榜前3名(降序,带分数)
redisReply *reply = (redisReply*)redisCommand(c, "ZREVRANGE borrow_rank 0 2 WITHSCORES");
if (reply->type == REDIS_REPLY_ARRAY) {
for (size_t i = 0; i < reply->elements; i += 2) {
std::string book_key = reply->element[i]->str; // 例如 "book:1001"
std::string score = reply->element[i+1]->str; // 借阅次数
std::cout << book_key << " : " << score << " times" << std::endl;
// 这里可以继续根据 book_key 从 SQLite 或 Redis 缓存中获取图书详情
}
}
freeReplyObject(reply);
redisFree(c);
return 0;
}协作流程总结
| 组件 | 职责 | Redis 操作 |
|---|---|---|
| Python 脚本 | 处理借书请求,保证原子更新 | ZINCRBY、INCR |
| C++ 主程序 | 展示排行榜,缓存热门数据 | ZREVRANGE,然后从 SQLite 或 Redis 字符串缓存读取详情 |
| SQLite | 持久化存储所有借阅历史、图书信息 | 无直接 Redis 操作 |
这种分工充分利用了 Redis 的高性能原子操作和 C++/Python 的各自优势。