使用 Redis 的 Set 结构可以方便地实现集合操作,比如求两个好友列表的交集(共同好友)、并集(所有好友)、补集(一个用户有而另一个没有的好友)。下面是如何使用 PHP 结合 MySQL 和 Redis 实现这些集合操作的示例。
1. 数据模型
假设每个用户的好友列表存储在 MySQL 中,并且在 Redis 中缓存这些好友关系。我们可以使用 Redis 的 Set 结构来实现集合操作。
2. 存储好友列表到 Redis
首先,从 MySQL 中获取用户的好友列表,并将其存储在 Redis 中的 Set 结构中。
<?php
function cacheFriendsToRedis($userId) {
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
// 从MySQL获取用户的好友列表
$db = new mysqli('localhost', 'username', 'password', 'database');
$stmt = $db->prepare("SELECT friend_id FROM user_friends WHERE user_id = ?");
$stmt->bind_param("i", $userId);
$stmt->execute();
$result = $stmt->get_result();
// 将好友列表存储到Redis的Set中
$friendSetKey = "friends:$userId";
$redis->del($friendSetKey); // 清空当前Set,防止重复数据
while ($row = $result->fetch_assoc()) {
$redis->sAdd($friendSetKey, $row['friend_id']);
}
}
3. 计算好友的交集、并集和补集
交集(共同好友)
计算两个用户之间的共同好友。
<?php
function getCommonFriends($userId1, $userId2) {
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
// 使用Redis的sInter命令求交集
$commonFriends = $redis->sInter("friends:$userId1", "friends:$userId2");
return $commonFriends;
}
// 示例:获取用户123和用户456的共同好友
$commonFriends = getCommonFriends(123, 456);
print_r($commonFriends);
并集(所有好友)
计算两个用户的所有好友(无重复)。
<?php
function getAllFriends($userId1, $userId2) {
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
// 使用Redis的sUnion命令求并集
$allFriends = $redis->sUnion("friends:$userId1", "friends:$userId2");
return $allFriends;
}
// 示例:获取用户123和用户456的所有好友
$allFriends = getAllFriends(123, 456);
print_r($allFriends);
补集(差集)
获取用户1有但用户2没有的好友(即在用户1好友列表中但不在用户2好友列表中的好友)。
<?php
function getDifferenceFriends($userId1, $userId2) {
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
// 使用Redis的sDiff命令求差集
$differenceFriends = $redis->sDiff("friends:$userId1", "friends:$userId2");
return $differenceFriends;
}
// 示例:获取用户123有但用户456没有的好友
$differenceFriends = getDifferenceFriends(123, 456);
print_r($differenceFriends);
4. 数据同步与更新
为了保持 Redis 中数据的最新状态,可以在每次用户添加或删除好友时,实时更新 Redis 中的 Set 结构,或定期从 MySQL 中同步数据到 Redis。
<?php
function addFriend($userId, $friendId) {
// 更新MySQL中的好友关系
$db = new mysqli('localhost', 'username', 'password', 'database');
$stmt = $db->prepare("INSERT INTO user_friends (user_id, friend_id) VALUES (?, ?)");
$stmt->bind_param("ii", $userId, $friendId);
$stmt->execute();
// 同步更新到Redis
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->sAdd("friends:$userId", $friendId);
}
总结
通过 Redis 的 Set 结构,可以高效地计算好友列表的交集、并集和补集。与 MySQL 结合使用时,既可以利用 Redis 的高速性,又能保证数据的持久性。这样在需要高频次访问和计算的场景中,例如社交应用的好友管理,可以显著提高系统性能。