如何用Redis实现朋友圈点赞功能?如何实现朋友圈点赞功能?

1 个回答

  • 楚狂人
    鸟随鸾凤飞腾远,人伴贤良品自高。
    ### **功能需求分析** 1. **记录点赞数量**:需要存储某条朋友圈的点赞总数。 2. **支持点赞和取消点赞**:用户可以点赞或取消点赞。 3. **查看点赞用户**:支持查看哪些用户点过赞。 4. **点赞时间顺序**:点赞记录按时间顺序排列,支持按时间范围查询。 ### **设计方案** #### **数据结构选择** - **`ZSet`(有序集合)**: - **Key**:某条朋友圈的唯一标识(如 `like:<postId>`)。 - **Value**:点赞用户的 ID。 - **Score**:点赞的时间戳,用于记录点赞时间并支持按时间排序。 #### **功能实现** 1. **点赞**: - 使用 `ZADD` 将用户 ID 添加到对应朋友圈的 ZSet 中,`score` 为当前时间戳。 - 如果用户已点过赞,则更新时间戳,避免重复点赞。 2. **取消点赞**: - 使用 `ZREM` 将用户 ID 从 ZSet 中移除。 3. **查看点赞用户**: - 使用 `ZRANGE` 或 `ZREVRANGE` 按照时间顺序获取点赞用户列表。 4. **查看点赞总数**: - 使用 `ZCARD` 获取 ZSet 的元素数量。 5. **按时间范围查询点赞用户**: - 使用 `ZRANGEBYSCORE` 或 `ZREVRANGEBYSCORE` 按时间范围获取用户列表。 ### **代码实现** 以下是基于 Java 和 Jedis 的实现代码: ```java import redis.clients.jedis.Jedis; import redis.clients.jedis.Tuple; import java.util.List; import java.util.Set; import java.util.stream.Collectors; public class RedisLikeDemo { private static final String LIKE_PREFIX = "like:"; // 点赞记录前缀 /** * 点赞操作 * @param postId 朋友圈 ID * @param userId 用户 ID * @param jedis Redis 客户端 */ public static void likePost(String postId, String userId, Jedis jedis) { String key = LIKE_PREFIX + postId; long now = System.currentTimeMillis(); jedis.zadd(key, now, userId); // 添加或更新点赞时间 } /** * 取消点赞 * @param postId 朋友圈 ID * @param userId 用户 ID * @param jedis Redis 客户端 */ public static void unlikePost(String postId, String userId, Jedis jedis) { String key = LIKE_PREFIX + postId; jedis.zrem(key, userId); // 移除点赞记录 } /** * 查看点赞用户列表 * @param postId 朋友圈 ID * @param jedis Redis 客户端 * @return 点赞用户 ID 列表 */ public static List<String> getLikes(String postId, Jedis jedis) { String key = LIKE_PREFIX + postId; Set<String> userIds = jedis.zrevrange(key, 0, -1); // 按时间倒序返回 return userIds.stream().collect(Collectors.toList()); } /** * 获取点赞总数 * @param postId 朋友圈 ID * @param jedis Redis 客户端 * @return 点赞总数 */ public static long getLikeCount(String postId, Jedis jedis) { String key = LIKE_PREFIX + postId; return jedis.zcard(key); // 获取点赞总数 } /** * 按时间范围获取点赞用户 * @param postId 朋友圈 ID * @param startTime 开始时间戳 * @param endTime 结束时间戳 * @param jedis Redis 客户端 * @return 点赞用户 ID 列表 */ public static List<String> getLikesByTime(String postId, long startTime, long endTime, Jedis jedis) { String key = LIKE_PREFIX + postId; Set<String> userIds = jedis.zrangeByScore(key, startTime, endTime); // 按时间范围获取用户 return userIds.stream().collect(Collectors.toList()); } public static void main(String[] args) { try (Jedis jedis = new Jedis("localhost", 6379)) { String postId = "123"; // 朋友圈 ID String userId1 = "user1"; String userId2 = "user2"; // 点赞 likePost(postId, userId1, jedis); likePost(postId, userId2, jedis); // 查看点赞用户 System.out.println("点赞用户:" + getLikes(postId, jedis)); // 获取点赞总数 System.out.println("点赞总数:" + getLikeCount(postId, jedis)); // 按时间范围查询 long startTime = System.currentTimeMillis() - 10000; long endTime = System.currentTimeMillis(); System.out.println("时间范围点赞用户:" + getLikesByTime(postId, startTime, endTime, jedis)); // 取消点赞 unlikePost(postId, userId1, jedis); System.out.println("取消点赞后用户:" + getLikes(postId, jedis)); } } } ``` ### **命令分析** 1. **ZADD**:添加或更新用户 ID 及点赞时间戳。 ```bash ZADD like:123 1699873200000 user1 ``` 2. **ZREM**:移除用户点赞。 ```bash ZREM like:123 user1 ``` 3. **ZRANGE** / **ZREVRANGE**:按时间顺序或逆序获取用户列表。 ```bash ZREVRANGE like:123 0 -1 ``` 4. **ZCARD**:获取点赞总数。 ```bash ZCARD like:123 ``` 5. **ZRANGEBYSCORE**:按时间范围获取点赞用户。 ```bash ZRANGEBYSCORE like:123 1699873100000 1699873200000 ``` ### **优势与扩展** #### **优势** 1. **去重和排序**:`ZSet` 自动去重并按时间戳排序。 2. **高效查询**:支持按时间范围、总数等多维度查询。 3. **实时性**:点赞和取消操作时间复杂度为 `O(log(N))`。 #### **扩展功能** 1. **分页查询点赞用户**:通过 `ZRANGE` 的 `start` 和 `end` 参数实现分页。 2. **点赞排行榜**:按点赞总数排名,可结合 Redis 的统计功能。 通过 Redis 的有序集合(ZSet),可以高效实现朋友圈点赞功能,满足去重、排序、实时查询等需求。
    发布于 2024-11-20 09:13 •IP属地 北京
    举报
    评论
    收藏