当前位置: 首页 > news >正文

唐山网站建设开发广州建设执业注册中心网站

唐山网站建设开发,广州建设执业注册中心网站,宣城网站建设公司,h5广告点赞 点赞业务比较频繁,很多人业务可能都会有这个,比如:博客,视频,文章,动态,评论等,但是不应该是核心业务,不应该大量地请求MySQL数据库,给数据库造成大量的资源消耗,MySQL的数据库是非常宝贵的. 以某音为例,当我去搜索的时候,全抖音比较高的点赞数目应该是在1200w - 2000w,…点赞 点赞业务比较频繁,很多人业务可能都会有这个,比如:博客,视频,文章,动态,评论等,但是不应该是核心业务,不应该大量地请求MySQL数据库,给数据库造成大量的资源消耗,MySQL的数据库是非常宝贵的. 以某音为例,当我去搜索的时候,全抖音比较高的点赞数目应该是在1200w - 2000w,我们自己的业务肯定答不到这么高的,但是假设有10个100w的点赞的博客,user_id为用户ID,publication_id为博客的id 第一种方式是直接操作数据库.每次有点赞或者取消点赞操作时,就更新MySQL数据库的点赞数.同时,插入或者更新一个user_id和publication_id的数据行,如果点赞操作非常频繁会对数据库产生很大的压力.如果有大量的点赞记录,会对数据库产生很大的数据量,一篇文章,100w的点赞的记录,对于MySQL来说,是非常恐怖的. 第二种方式是通过MySQL Redis的Set来实现,具体代码如下,以下的代码为B站Redis黑马点评项目: Override public Result likeBlog(Long id){// 1. 获取登录用户Long userId UserHolder.getUser().getId();// 2. 判断当前登录用户是否已经点赞String key BLOG_LIKED_KEY id;Boolean isMember stringRedisTemplate.opsForSet().isMember(key, userId.toString());if(BooleanUtil.isFalse(isMember)){// 3. 如果未点赞可以点赞// 3.1 数据库点赞数1boolean isSuccess update().setSql(liked liked 1).eq(id, id).update();// 3.2 保存用户到Redis的set集合if(isSuccess){stringRedisTemplate.opsForSet().add(key, userId.toString());}} else {// 4. 如果已点赞取消点赞// 4.1 数据库点赞数-1boolean isSuccess update().setSql(liked liked - 1).eq(id, id).update();// 4.2 把用户从Redis的set集合移除if(isSuccess){stringRedisTemplate.opsForSet().remove(key, userId.toString());}} } 这样造成的问题是,Redis是内存数据库点赞信息存储在内存中。当点赞数量非常大时会占用大量内存。 下面测试一下,一个key为userId:114514:publication_id:738836,value为100000-1100000的数据 数据量 scard userId:114514:publication_id:738836判断一个value是否存在这个set中-----(对应的业务为判断当前登录用户是否已经点赞) Testpublic void selectBigKey() {String key userId:114514:publication_id:738836;String value1 100000;String value2 5000000;// 记录开始时间long startTime System.nanoTime();boolean cacheSet1 RedisUtils.containsInCacheSet(key, value1);if (cacheSet1) {System.out.println(代码2: 存在这个value);} else {System.out.println(代码2: 不存在这个value);}// 记录结束时间long endTime System.nanoTime();// 计算执行时间以毫秒为单位long executionTime (endTime - startTime) / 1_000_000; // 将纳秒转换为毫秒System.out.println(代码执行时间1: executionTime 毫秒);// 记录开始时间long startTime2 System.nanoTime();boolean cacheSet2 RedisUtils.containsInCacheSet(key, value2);if (cacheSet2) {System.out.println(代码2: 存在这个value);} else {System.out.println(代码2: 不存在这个value);}// 记录结束时间long endTime2 System.nanoTime();// 计算执行时间以毫秒为单位long executionTime2 (endTime2 - startTime2) / 1_000_000; // 将纳秒转换为毫秒System.out.println(代码执行时间2: executionTime2 毫秒);}可以看到,其实对于时间来说,61毫秒和66毫秒可以说时间非常短了,不愧是redis,即使数据量很大,但是查询一个value是否在比较大的set的效率是非常短的. 往一个key中添加一个value,或者删除一个value---(对应一个点赞,和取消点赞) Testpublic void addAndRemoveElementFromBigKey() {String key userId:114514:publication_id:738836;String value1 10000000;String value2 200000;// 记录开始时间long startTime System.nanoTime();boolean cacheSet1 RedisUtils.addToCacheSet(key, value1);// 记录结束时间long endTime System.nanoTime();// 计算执行时间以毫秒为单位long executionTime (endTime - startTime) / 1_000_000; // 将纳秒转换为毫秒System.out.println(添加一个元素的执行时间: executionTime 毫秒);// 记录开始时间long startTime2 System.nanoTime();boolean cacheSet2 RedisUtils.removeFromCacheSet(key, value2);// 记录结束时间long endTime2 System.nanoTime();// 计算执行时间以毫秒为单位long executionTime2 (endTime2 - startTime2) / 1_000_000; // 将纳秒转换为毫秒System.out.println(删除一个元素的代码执行时间: executionTime2 毫秒);}但从时间来讲,只有一个字:快 查询占用的内存的空间 MEMORY USAGE userId:114514:publication_id:738836​ 其实可以看到,大概是占用66mb,如果用户的id为雪花算法的id,那可能占用的内存100mb 以上来说,主要还是一个bigkey的问题,如果点赞的数量过大,占用的内存过大,宝贵的内存不应该给这种业务. 自然而然,我们想到用非关系型数据库,但是不要是基于内存的,我想到的是用MongoDB的方案 我们可以往MongoDB中插入一条这样的数据: db.collectionName.insertOne({id: yourIdValue,userId: yourUserIdValue,type: yourTypeValue,likedItemId: yourLikedItemIdValue,createTime: new Date(yourCreateTimeValue) }); id 主键id,userId为用户的ID,type为文章或者动态或者其他的类型,likedItemId为文章或者动态或者其他的类型的主键ID,createTime为点赞时间 在MongoDB中可以使用createIndex方法来创建唯一索引。为userId,type和likedItemId字段创建一个唯一索引。 db.collectionName.createIndex({ userId: 1, type: 1, likedItemId: 1 },{ unique: true, name: unique_index_name } );详细解释: collectionName集合名称。unique_index_name你想要给索引起的名字可以根据你的需求替换为其他名称。这个命令将在collectionName集合上创建一个名为unique_index_name的唯一索引涵盖了userId、type和likedItemId字段。 1表示升序如果需要降序索引可以使用-1。 unique: true选项确保索引是唯一的。 执行这个命令后如果有重复的组合出现在这三个字段上MongoDB将会阻止插入并抛出错误。 即如果里面有记录为已经点过赞,点赞就是往里面加记录,取消点赞就是删除记录 详细代码如下: Service public class LikeServiceImpl implements LikeService {Autowiredprivate MongoTemplate mongoTemplate;Autowiredprivate PublicationService publicationService;/*** 为动态或者文章点赞** param publicationId 动态或者文章的ID* param userId 用户的ID* param type 类型,区分是文章还是动态* return 点赞总数*/Overridepublic Integer likePublication(Long publicationId, Long userId, Integer type) {// 构建查询条件Criteria criteria Criteria.where(userId).is(userId).and(type).is(type).and(likedItemId).is(publicationId);// 创建查询对象并应用查询条件Query query new Query(criteria);boolean isExists mongoTemplate.exists(query, PublicationLike.class);if (isExists) {Asserts.fail(重复点赞);}//将点赞记录保存到mongodbPublicationLike publicationLike new PublicationLike();publicationLike.setType(type);publicationLike.setCreateTime(DateUtil.date());publicationLike.setLikedItemId(publicationId);publicationLike.setUserId(userId);PublicationLike savedLike mongoTemplate.save(publicationLike);//点赞数统计String redisLikeCountKey String.format(RedisConstant.PUBLICATION_LIKE_COUNT, publicationId, userId, type);Long likeCount RedisUtils.getAtomicValueWithDefault(redisLikeCountKey);//如果没有缓存过点赞数,则查询数据库if (likeCount.equals(-1L)) {Publication publication publicationService.getById(publicationId);RedisUtils.setAtomicValue(redisLikeCountKey, publication.getLikeCount());return publication.getLikeCount();} else {//返回点赞数1return Math.toIntExact(RedisUtils.incrAtomicValue(redisLikeCountKey));}}Overridepublic Integer unlikePublication(Long publicationId, Long userId, Integer type) {// 构建查询条件Criteria criteria Criteria.where(userId).is(userId).and(type).is(type).and(likedItemId).is(publicationId);// 创建查询对象并应用查询条件Query query new Query(criteria);boolean isExists mongoTemplate.exists(query, PublicationLike.class);if (!isExists) {Asserts.fail(未点赞过该内容无法取消点赞);}// 从MongoDB中删除点赞记录mongoTemplate.remove(query, PublicationLike.class);// 更新点赞数统计String redisLikeCountKey String.format(RedisConstant.PUBLICATION_LIKE_COUNT, publicationId, userId, type);Long likeCount RedisUtils.getAtomicValueWithDefault(redisLikeCountKey);// 如果点赞数存在于缓存中减少点赞数并返回if (!likeCount.equals(-1L)) {long newLikeCount RedisUtils.decrAtomicValue(redisLikeCountKey);return Math.toIntExact(newLikeCount);} else {// 如果点赞数没有缓存查询数据库并更新缓存Publication publication publicationService.getById(publicationId);if (publication ! null) {RedisUtils.setAtomicValue(redisLikeCountKey, publication.getLikeCount());return publication.getLikeCount();} else {Asserts.fail(无法获取点赞数);return 0;}}}}
http://www.yutouwan.com/news/487237/

相关文章:

  • 建筑装饰和网站建设哪个好wordpress图片模版
  • 设计师接单的网站前端开发和后端开发哪个好
  • 网站第三方微信登陆怎么做的网站建设共享
  • 类似wordpress的建站系统仿团购网站模板
  • 高端网站开发成本凌云县城乡建设局网站
  • dede修改网站密码wordpress 朴素
  • 濮阳做网站推广的公司wordpress修改主题文件夹
  • 沈阳做网站的企业食品类建设网站的目的
  • 南宁关键词优化软件seo品牌优化百度资源网站推广关键词排名
  • 大兴网站建设制作西安易网信息技术有限公司
  • 虚拟物品网站制作模板福建省法冶建设知识有奖网站
  • 无锡网站建设价格费用室内装修设计图用什么软件
  • 网站为什么要备案在家做网站设计挣钱吗
  • 建行网站登录wordpress添加底部漂浮栏菜单
  • 提升seo排名平台苏州长尾词seo排名优化
  • 手表网站欧米茄官网玉林专业网站建设
  • 个体做外贸的网站电商网站模板下载
  • 做网站的需求网站域名年费
  • 网站建设淘宝属于什么类目网站建设的拓扑结构
  • 网站制作论文题目书画网站模板asp
  • 江苏省交通建设局网站首页网站制作 合肥
  • 建设网站基本步骤朝阳改版网站
  • 手机wap网站开发学校网站建设要求
  • 联想公司网站建设现状建设厅网站打不开
  • 网站域名服务器查询镇江专业网站制作公司
  • 徐州网站设计价位淄博企业建网站
  • 东莞建网站公司哪个好企业做网站设置哪些模块
  • 优秀平面设计网站域名服务网站
  • 为什么电子网站开发专业的家居行业网站模板
  • 深圳辰硕网站优化黄页软件app大全