《步伐猿之Redis缓存实战 · 位图范例》

[复制链接]
发表于 2026-1-16 11:44:58 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
📢 各人好,我是 【战神刘玉栋】,有10多年的研发履历,致力于前后端技能栈的知识沉淀和流传。 💗
  🌻 CSDN入驻不久,盼望各人多多支持,后续会继承提升文章质量,绝不滥竽充数,接待多多交换。👍
  


位图(Bitmap)

【简介】
Bitmap 存储的是连续的二进制数字(0 和 1),通过 Bitmap, 只须要一个 bit 位来表现某个元素对应的值大概状态,key 就是对应元素自己 。我们知道 8 个 bit 可以构成一个 byte,以是 Bitmap 自己会极大的节省储存空间。
【应用场景】
须要生存状态信息(0/1 即可表现)的场景
● 举例:用户签到情况、生动用户情况、用户活动统计(比如是否点赞过某个视频)。
● 干系下令:SETBIT、GETBIT、BITCOUNT、BITOP。
【根本操纵】
  1. setbit key offset val:给指定key的值的第offset赋值val 时间复杂度:O(1)
  2. getbit key offset:获取指定key的第offset位 时间复杂度:O(1)
  3. bitcount key start end:返回指定key中[ start,end ]中为1的数量 时间复杂度:O(n)
  4. BITPOS key bit start end:查找字符串中第一个设置为1或0的位的位置
复制代码
【实战 - 文章点赞】
利用 Redis 的 Bitmaps 来处理处罚文章的点赞功能是一个非常符合的选择,尤其是在须要高效存储和快速查询的场景中。Bitmaps 答应你以位(bit)为单位存储数据,如许可以节省存储空间并进步性能。
为什么利用 Bitmaps?


  • 节省空间:每个用户的点赞状态只须要一个比特位(0 或 1),而不是存储整个用户 ID。
  • 高效查询:可以快速查抄某个用户是否点赞,以及统计点赞总数。
示例阐明:
假设我们有一个文章 ID 为 article:123 的文章,用户 ID 为 user:456,我们可以利用 Redis 的 Bitmaps 来记载用户的点赞状态。起首,利用 Bitmap 来表现每个用户对每篇文章的点赞状态,假设文章的 ID 是 articleId,用户的 ID 是 userId,可以利用 SETBIT 下令来设置用户对文章的点赞状态。
此中:article:{articleId}:likes 作为键,用户 ID 作为偏移量。
   留意事项:这里用户ID必须是数字范例。
  Step1、编写业务逻辑
  1. @Service
  2. public class ArticleService {
  3.     @Autowired
  4.     private RedisTemplate<String, Object> redisTemplate;
  5.     private static final String LIKE_KEY_PREFIX = "article:%s:likes";
  6.     // 点赞
  7.     public void likeArticle(Long articleId, Long userId) {
  8.         String key = String.format(LIKE_KEY_PREFIX, articleId);
  9.         redisTemplate.opsForValue()
  10.                 .setBit(key, userId.intValue(), true);
  11.     }
  12.     // 取消点赞
  13.     public void unlikeArticle(Long articleId, Long userId) {
  14.         String key = String.format(LIKE_KEY_PREFIX, articleId);
  15.         redisTemplate.opsForValue()
  16.                 .setBit(key, userId.intValue(), false);
  17.     }
  18.     // 获取点赞数量
  19.     public Long getLikeCount(Long articleId) {
  20.         String key = String.format(LIKE_KEY_PREFIX, articleId);
  21.         Long bitCount = redisTemplate.execute((RedisCallback<Long>) connection ->
  22.                 connection.bitCount(key.getBytes()), true);
  23.         return bitCount != null ? bitCount : 0;
  24.     }
  25.     // 检查用户是否点赞
  26.     public boolean hasLiked(Long articleId, Long userId) {
  27.         String key = String.format(LIKE_KEY_PREFIX, articleId);
  28.         return Boolean.TRUE.equals(redisTemplate.opsForValue()
  29.                 .getBit(key, userId.intValue()));
  30.     }
  31. }
复制代码
Step2、编写控制器
  1. @RestController
  2. @RequestMapping("/articles")
  3. public class ArticleController {
  4.     @Autowired
  5.     private ArticleService articleService;
  6.     /**
  7.      * 用户点赞
  8.      * @param articleId 文章ID
  9.      * @param userId 用户ID
  10.      */
  11.     @PostMapping("/{articleId}/like/{userId}")
  12.     public ResponseEntity<String> likeArticle(@PathVariable Long articleId, @PathVariable Long userId) {
  13.         articleService.likeArticle(articleId, userId);
  14.         return ResponseEntity.ok("OK");
  15.     }
  16.     /**
  17.      * 用户取消点赞
  18.      * @param articleId 文章ID
  19.      * @param userId 用户ID
  20.      */
  21.     @PostMapping("/{articleId}/unlike/{userId}")
  22.     public ResponseEntity<String> unlikeArticle(@PathVariable Long articleId, @PathVariable Long userId) {
  23.         articleService.unlikeArticle(articleId, userId);
  24.         return ResponseEntity.ok("OK");
  25.     }
  26.     /**
  27.      * 获取某文章的点赞数量
  28.      * @param articleId 文章ID
  29.      */
  30.     @GetMapping("/{articleId}/likes/count")
  31.     public ResponseEntity<Long> getLikeCount(@PathVariable Long articleId) {
  32.         Long count = articleService.getLikeCount(articleId);
  33.         return ResponseEntity.ok(count);
  34.     }
  35.     /**
  36.      * 判断用户是否点赞
  37.      * @param articleId 文章ID
  38.      * @param userId 用户ID
  39.      */
  40.     @GetMapping("/{articleId}/like/{userId}")
  41.     public ResponseEntity<Boolean> hasLiked(@PathVariable Long articleId, @PathVariable Long userId) {
  42.         boolean hasLiked = articleService.hasLiked(articleId, userId);
  43.         return ResponseEntity.ok(hasLiked);
  44.     }
  45. }
复制代码

回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表