马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
📢 各人好,我是 【战神刘玉栋】,有10多年的研发履历,致力于前后端技能栈的知识沉淀和流传。 💗
🌻 CSDN入驻不久,盼望各人多多支持,后续会继承提升文章质量,绝不滥竽充数,接待多多交换。👍
位图(Bitmap)
【简介】
Bitmap 存储的是连续的二进制数字(0 和 1),通过 Bitmap, 只须要一个 bit 位来表现某个元素对应的值大概状态,key 就是对应元素自己 。我们知道 8 个 bit 可以构成一个 byte,以是 Bitmap 自己会极大的节省储存空间。
【应用场景】
须要生存状态信息(0/1 即可表现)的场景
● 举例:用户签到情况、生动用户情况、用户活动统计(比如是否点赞过某个视频)。
● 干系下令:SETBIT、GETBIT、BITCOUNT、BITOP。
【根本操纵】
- setbit key offset val:给指定key的值的第offset赋值val 时间复杂度:O(1)
- getbit key offset:获取指定key的第offset位 时间复杂度:O(1)
- bitcount key start end:返回指定key中[ start,end ]中为1的数量 时间复杂度:O(n)
- 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、编写业务逻辑
- @Service
- public class ArticleService {
- @Autowired
- private RedisTemplate<String, Object> redisTemplate;
- private static final String LIKE_KEY_PREFIX = "article:%s:likes";
- // 点赞
- public void likeArticle(Long articleId, Long userId) {
- String key = String.format(LIKE_KEY_PREFIX, articleId);
- redisTemplate.opsForValue()
- .setBit(key, userId.intValue(), true);
- }
- // 取消点赞
- public void unlikeArticle(Long articleId, Long userId) {
- String key = String.format(LIKE_KEY_PREFIX, articleId);
- redisTemplate.opsForValue()
- .setBit(key, userId.intValue(), false);
- }
- // 获取点赞数量
- public Long getLikeCount(Long articleId) {
- String key = String.format(LIKE_KEY_PREFIX, articleId);
- Long bitCount = redisTemplate.execute((RedisCallback<Long>) connection ->
- connection.bitCount(key.getBytes()), true);
- return bitCount != null ? bitCount : 0;
- }
- // 检查用户是否点赞
- public boolean hasLiked(Long articleId, Long userId) {
- String key = String.format(LIKE_KEY_PREFIX, articleId);
- return Boolean.TRUE.equals(redisTemplate.opsForValue()
- .getBit(key, userId.intValue()));
- }
- }
复制代码 Step2、编写控制器
- @RestController
- @RequestMapping("/articles")
- public class ArticleController {
- @Autowired
- private ArticleService articleService;
- /**
- * 用户点赞
- * @param articleId 文章ID
- * @param userId 用户ID
- */
- @PostMapping("/{articleId}/like/{userId}")
- public ResponseEntity<String> likeArticle(@PathVariable Long articleId, @PathVariable Long userId) {
- articleService.likeArticle(articleId, userId);
- return ResponseEntity.ok("OK");
- }
- /**
- * 用户取消点赞
- * @param articleId 文章ID
- * @param userId 用户ID
- */
- @PostMapping("/{articleId}/unlike/{userId}")
- public ResponseEntity<String> unlikeArticle(@PathVariable Long articleId, @PathVariable Long userId) {
- articleService.unlikeArticle(articleId, userId);
- return ResponseEntity.ok("OK");
- }
- /**
- * 获取某文章的点赞数量
- * @param articleId 文章ID
- */
- @GetMapping("/{articleId}/likes/count")
- public ResponseEntity<Long> getLikeCount(@PathVariable Long articleId) {
- Long count = articleService.getLikeCount(articleId);
- return ResponseEntity.ok(count);
- }
- /**
- * 判断用户是否点赞
- * @param articleId 文章ID
- * @param userId 用户ID
- */
- @GetMapping("/{articleId}/like/{userId}")
- public ResponseEntity<Boolean> hasLiked(@PathVariable Long articleId, @PathVariable Long userId) {
- boolean hasLiked = articleService.hasLiked(articleId, userId);
- return ResponseEntity.ok(hasLiked);
- }
- }
复制代码
|