点赞功能设计与实现

点赞功能设计与实现

点赞业务本身并不复杂,无非是对数据的update,但是点赞本身是无意识行为,并且同一个用户可对博文进行点赞/取消点赞,如果直接操作数据库,无疑会增加数据库io操作。

方案:

缓存+异步推送 缓存+定时任务优点:

降低对数据库的操作提高点赞的效率缺点:

redis挂掉,或者mq延迟使数据库数据与redis数据不一致(正在发生)

解决方案:定时同步redis与数据库数据丢失数据

解决方案:MQ挂掉,不解决

数据库设计

代码语言:javascript复制CREATE TABLE `user_thumb` (

`like_detail_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '点赞信息ID',

`info_id` bigint(8) DEFAULT NULL COMMENT '图文ID',

`like_create_time` datetime(0) DEFAULT NULL COMMENT '时间',

`like_user_id` bigint(8) DEFAULT NULL COMMENT '点赞人ID',

PRIMARY KEY (`like_detail_id`) USING BTREE

) ENGINE = InnoDB AUTO_INCREMENT = 16 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '点赞记录表' ROW_FORMAT = Dynamic;

实现思路

1.方案一

redis数据结构采用hash或者set都可,前缀自定义,后缀使用图文消息的id

key-value------>{“prefix:图文id” : “用户id”}

2.大key类型拆分

即便是一万用户,频繁操作最大值也是非常大的,对key进行hash取值,

代码语言:javascript复制String key = RedisConstants.getLike(infoId%6);

boolean flag = redisService.isMember(key, userId);

3.是否点赞枚举,1:点赞,2:取消点赞

代码语言:javascript复制public enum ThumbEnum {

THUMB(1,"点赞"),

CANCELTHUMB(2,"取消点赞"),

private String MessageName;

private Integer type;

public String getType(Integer type) {

return type;

}

public void setMessageName(String messageName) {

MessageName = messageName;

}

ThumbEnum(String messageName) {

MessageName = messageName;

}

}

4.接口实现

根据是否存在key判断是点赞还是取消点赞,所以接口写一个即可

代码语言:javascript复制Json thumbOrCancel(Long infoId,Long userId);impl

代码语言:javascript复制 String key = RedisConstants.getLike(infoId.toString());

String userIdstr = userId.toString();

//是否已经点过赞

boolean flag = jedisService.isMember(key, userIdstr);

ThumbVo vo = ThumbVo.builder()

.infoId(infoId)

.likeCreateTime(new Date())

.userId(userId)

.build();

Map map = new HashMap();

if (flag) {

//已点过赞则为取消赞操作

redisService.srem(key, userIdStr);

vo.setType(2);//1点赞2取消赞

map.put("isLike", 1);//1未点赞2已点赞

} else {

//记录点赞用户

redisService.sadd(key, userIdStr);

vo.setType(1);

map.put("isLike", 2);

}

//发送消息

userThumbProducer.senduserThumbUp(vo);

resultMap.put("likeCount", redisService.scard(key));

return Json.newInstance(resultMap);mq

异步去消费调用数据库即可,如果做定时任务去查redis是否有数据,持久化到mysql。

按理说读取与写操作应该分为两个redis,但是点赞统计的是评论数,大key进行拆分后,无需对其读写分离。

相关推荐

铁岭无痛人流?
365bet世界

铁岭无痛人流?

📅 08-15 👁️ 5547
不孕不育要去看哪个科?
365bet世界

不孕不育要去看哪个科?

📅 10-08 👁️ 1194
体毛刮了多久能长出来
365信誉线上

体毛刮了多久能长出来

📅 08-01 👁️ 2348
《神仙劫-开服多久后合服?》
365信誉线上

《神仙劫-开服多久后合服?》

📅 09-22 👁️ 9666
数字谐音对照表
365bet亚洲真人网

数字谐音对照表

📅 07-29 👁️ 3157
apple id 账户登录icloud连接错误
365bet亚洲真人网

apple id 账户登录icloud连接错误

📅 10-03 👁️ 7280
小米账号锁怎么解除?官方解锁教程来了!
365bet世界

小米账号锁怎么解除?官方解锁教程来了!

📅 07-21 👁️ 3648