Appearance
第15章:基础实战(新手必练,逐个突破)
实战1:用户登录会话存储(String类型实战)
15.1 需求分析
实现一个用户登录会话存储系统,需要:
- 用户登录后,将会话信息存储到Redis
- 设置会话过期时间(如30分钟)
- 用户退出时删除会话
- 支持会话查询和验证
15.2 核心实现
- String类型命令:SET EX(设置带过期时间的键值对)、GET(获取会话信息)、DEL(删除会话)
- 过期时间设置:使用EX参数设置过期时间
- 会话ID生成:使用UUID或随机字符串作为会话标识
15.3 实操步骤
步骤1:生成会话ID并存储会话信息
bash
# 连接Redis
redis-cli
# 生成会话ID(实际应用中使用UUID)
SET session:user:123 "{\"user_id\": 123, \"username\": \"zhangsan\", \"login_time\": \"2026-04-03 10:00:00\"}" EX 1800
# 验证会话是否设置成功
GET session:user:123步骤2:模拟用户操作期间会话验证
bash
# 检查会话是否存在
EXISTS session:user:123
# 获取会话信息
GET session:user:123
# 查看会话剩余过期时间
TTL session:user:123步骤3:用户退出,删除会话
bash
# 删除会话
DEL session:user:123
# 验证会话是否已删除
GET session:user:12315.4 代码实现(Node.js示例)
javascript
const redis = require('redis');
const client = redis.createClient();
const { v4: uuidv4 } = require('uuid');
// 用户登录
function login(username, password) {
// 验证用户凭证(实际应用中需要查询数据库)
if (username === 'zhangsan' && password === '123456') {
const userId = 123;
const sessionId = uuidv4();
const sessionData = {
user_id: userId,
username: username,
login_time: new Date().toISOString()
};
// 存储会话信息,设置30分钟过期
client.set(`session:${sessionId}`, JSON.stringify(sessionData), 'EX', 1800);
return { success: true, sessionId: sessionId };
}
return { success: false, message: '用户名或密码错误' };
}
// 验证会话
function validateSession(sessionId) {
return new Promise((resolve, reject) => {
client.get(`session:${sessionId}`, (err, data) => {
if (err) reject(err);
if (data) {
resolve({ valid: true, user: JSON.parse(data) });
} else {
resolve({ valid: false, message: '会话已过期或不存在' });
}
});
});
}
// 用户退出
function logout(sessionId) {
client.del(`session:${sessionId}`);
return { success: true, message: '已成功退出' };
}
// 使用示例
async function testSession() {
// 登录
const loginResult = login('zhangsan', '123456');
console.log('登录结果:', loginResult);
if (loginResult.success) {
const sessionId = loginResult.sessionId;
// 验证会话
const validateResult = await validateSession(sessionId);
console.log('会话验证结果:', validateResult);
// 退出
const logoutResult = logout(sessionId);
console.log('退出结果:', logoutResult);
// 再次验证会话
const validateAfterLogout = await validateSession(sessionId);
console.log('退出后会话验证结果:', validateAfterLogout);
}
}
testSession();实战2:商品信息缓存(Hash类型实战)
15.4 需求分析
实现一个商品信息缓存系统,需要:
- 将商品信息(ID、名称、价格、库存)缓存到Redis
- 支持商品信息的查询
- 支持商品信息的修改
- 支持商品信息的删除
- 提高商品信息的访问速度
15.5 核心实现
- Hash类型命令:HSET(设置哈希字段)、HGETALL(获取所有字段和值)、HDEL(删除哈希字段)、HMSET(批量设置哈希字段)
- 键命名规范:使用
product:{id}作为哈希键 - 数据结构:使用哈希类型存储商品的多个属性
15.6 实操步骤
步骤1:存储商品信息
bash
# 连接Redis
redis-cli
# 方法1:使用HSET逐个设置字段
HSET product:1001 id 1001
HSET product:1001 name "iPhone 15"
HSET product:1001 price 5999
HSET product:1001 stock 100
# 方法2:使用HMSET批量设置字段
HMSET product:1002 id 1002 name "MacBook Pro" price 12999 stock 50步骤2:查询商品信息
bash
# 获取商品所有信息
HGETALL product:1001
# 获取商品特定字段
HGET product:1001 name
HGET product:1001 price步骤3:修改商品信息
bash
# 修改商品价格
HSET product:1001 price 5499
# 修改商品库存
HSET product:1001 stock 95
# 验证修改结果
HGETALL product:1001步骤4:删除商品信息
bash
# 删除商品的某个字段
HDEL product:1001 stock
# 验证删除结果
HGETALL product:1001
# 删除整个商品信息
DEL product:1001
# 验证商品是否已删除
HGETALL product:100115.7 代码实现(PHP示例)
php
<?php
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
// 存储商品信息
function saveProduct($redis, $id, $name, $price, $stock) {
$key = "product:{$id}";
$redis->hMSet($key, [
'id' => $id,
'name' => $name,
'price' => $price,
'stock' => $stock
]);
return true;
}
// 获取商品信息
function getProduct($redis, $id) {
$key = "product:{$id}";
return $redis->hGetAll($key);
}
// 更新商品信息
function updateProduct($redis, $id, $data) {
$key = "product:{$id}";
foreach ($data as $field => $value) {
$redis->hSet($key, $field, $value);
}
return true;
}
// 删除商品信息
function deleteProduct($redis, $id) {
$key = "product:{$id}";
return $redis->del($key);
}
// 使用示例
saveProduct($redis, 1001, "iPhone 15", 5999, 100);
echo "商品信息:\n";
print_r(getProduct($redis, 1001));
updateProduct($redis, 1001, ['price' => 5499, 'stock' => 95]);
echo "\n更新后商品信息:\n";
print_r(getProduct($redis, 1001));
deleteProduct($redis, 1001);
echo "\n删除后商品信息:\n";
print_r(getProduct($redis, 1001));
$redis->close();
?>实战3:商品销量排行榜(Sorted Set类型实战)
15.7 需求分析
实现一个商品销量排行榜系统,需要:
- 统计商品销量
- 实现销量降序排名
- 展示前10名商品
- 支持实时更新销量
15.8 核心实现
- Sorted Set类型命令:ZADD(添加元素及分数)、ZREVRANGE(降序获取元素)、ZINCRBY(增加元素分数)
- 键命名规范:使用
sales:rank作为有序集合键 - 分数设置:使用商品销量作为分数
15.9 实操步骤
步骤1:初始化商品销量数据
bash
# 连接Redis
redis-cli
# 添加商品销量数据
ZADD sales:rank 100 1001 # 商品1001销量100
ZADD sales:rank 150 1002 # 商品1002销量150
ZADD sales:rank 80 1003 # 商品1003销量80
ZADD sales:rank 200 1004 # 商品1004销量200
ZADD sales:rank 120 1005 # 商品1005销量120步骤2:更新商品销量
bash
# 商品1001销量增加20
ZINCRBY sales:rank 20 1001
# 商品1003销量增加30
ZINCRBY sales:rank 30 1003步骤3:获取销量排行榜
bash
# 获取销量前3名商品(降序)
ZREVRANGE sales:rank 0 2 WITHSCORES
# 获取销量前10名商品
ZREVRANGE sales:rank 0 9 WITHSCORES步骤4:查询特定商品的销量和排名
bash
# 获取商品1001的销量
ZSCORE sales:rank 1001
# 获取商品1001的排名(降序,从0开始)
ZREVRANK sales:rank 100115.10 代码实现(Python示例)
python
import redis
# 连接Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# 初始化商品销量
def init_sales():
# 清除现有排行榜
r.delete('sales:rank')
# 添加初始销量数据
sales_data = {
'1001': 100,
'1002': 150,
'1003': 80,
'1004': 200,
'1005': 120
}
for product_id, sales in sales_data.items():
r.zadd('sales:rank', {product_id: sales})
print("初始化销量数据完成")
# 更新商品销量
def update_sales(product_id, increment):
r.zincrby('sales:rank', increment, product_id)
print(f"商品{product_id}销量增加{increment}")
# 获取销量排行榜
def get_sales_rank(top_n=10):
# 获取降序排列的前N个商品
rank = r.zrevrange('sales:rank', 0, top_n-1, withscores=True)
print(f"\n销量排行榜(前{top_n}名):")
for i, (product_id, sales) in enumerate(rank, 1):
print(f"第{i}名:商品{product_id},销量{int(sales)}")
# 获取商品排名和销量
def get_product_rank(product_id):
sales = r.zscore('sales:rank', product_id)
rank = r.zrevrank('sales:rank', product_id)
if sales is not None:
print(f"\n商品{product_id}:")
print(f"销量:{int(sales)}")
print(f"排名:第{rank+1}名")
else:
print(f"商品{product_id}不存在")
# 使用示例
if __name__ == "__main__":
init_sales()
get_sales_rank(5)
# 更新销量
update_sales('1001', 50)
update_sales('1003', 100)
# 查看更新后的排行榜
get_sales_rank(5)
# 查看特定商品排名
get_product_rank('1001')
get_product_rank('1003')实战总结
通过以上三个基础实战案例,我们学习了:
- String类型:适合存储会话信息、验证码等简单数据,支持设置过期时间
- Hash类型:适合存储对象信息,如商品详情、用户信息等,支持单独修改字段
- Sorted Set类型:适合实现排行榜、排名等功能,支持根据分数排序
这些实战案例覆盖了Redis最常用的数据类型和命令,是新手入门的必备练习。在实际应用中,我们可以根据具体场景选择合适的数据类型和命令,以达到最佳的性能和效果。
