# like_demo **Repository Path**: xcoconut/like_demol ## Basic Information - **Project Name**: like_demo - **Description**: 使用redis和mysql实现点赞的小demo - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2022-08-09 - **Last Updated**: 2022-08-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README **redis中数据存储分为两类:** A:文章id + 点赞总数 B:文章id + 用户id + status(该用户是否点赞过,假设1为已点赞,0为未点赞),使用Hash存储 **Mysql中数据存储可以分为三类** C:用户信息(用户id以及用户的其它信息) D:文章信息(文章id,文章内容,点赞总数,...) E:点赞记录表(文章id,用户id) ​ 查询:从D表中查询文章数据基本信息(文章id,内容,...),遍历数据集合: * 查询每一篇文章的点赞总数:根据文章id先从redis中查询文章总数,如果有就直接查询返回填充,若没有就从数据库中查询该文章的点赞总数(这时候说明 MySQL中该文章的点赞总数是最新的)。 * 查询该用户是否已经点赞过该文章:根据文章id,从redis中查询B中是否有存在文章id+用户id,若存在,则直接查询返回status的值(1为已点赞,0为未点赞);若不存在,则再查询数据库中的点赞记录即E表,若文章id+用户id出现在记录表中,则表明该用户已经点赞过该文章,记录状态值为1(已点赞),否则记为0(未点赞) 点赞: * 判断B中是否存在对应的文章id + 用户id ,若存在,判断status是否为0,为0则将status的值从0改为1(客户端也需要做同样的改变),否则直接返回或者抛出异常(有人在刷赞);如果不存在则从数据记录表E表中查询是否存在对应的文章id + 用户id,不存在需要在B中添加文章id + 用户id + status(status此时为1),若存在则直接返回或者抛出异常(有人在刷赞). * 最后在确认无人刷赞的情况下需要将A中文章id对应的点赞总数加1,若A中不存在该文章id,则需要根据文章id将数据库的D表对应文章的点赞总数加1再返回,再在A中添加对应的文章id + 点赞总数 取消点赞: * 判断B中是否存在对应的文章id + 用户id ,若存在, 判断status是否为1,为1则将status的值从1改为0(客户端也需要做同样的改变)否则直接返回或者抛出异常(有人在故意拉踩);如果不存在则从数据记录表E表中查询是否存在对应的文章id + 用户id,存在则需要在B中添加文章id + 用户id + status(status此时为0),否则直接返回或者抛出异常(有人在故意拉踩). * 最后在确认无人在故意拉踩的情况下需要将A中文章id对应的点赞总数减1(需要判断总数是否为0),若A中不存在该文章id,则需要根据文章id将数据库的D表对应文章的点赞总数减一1再返回,再在A中添加对应的文章id + 点赞总数 定时任务:将redis中的数据刷新到数据库中 * B中文章id + 用户id + status刷新到E中,根据status做判断,status为1则添加记录,为0则删除对应记录(记得判空和去重) * A中文章id + 点赞总数对应刷新到D中 * 定时任务要确保redis中的数据最后都会更新到数据库中(时间间隔应小于redis数据的过期时间) * redis中的数据保存到数据库中时更新一个就删除一个(删除的目的主要是为了防止redis占用内存过大,因为hash中的数据基本一直在更新,过期时间也随之一直在刷新,但点赞总数我感觉可以不用删除)