深圳市专业制作网站公司/搜索引擎营销概念

深圳市专业制作网站公司,搜索引擎营销概念,上海最新动态,网页编辑器安卓点赞 点赞业务比较频繁,很多人业务可能都会有这个,比如:博客,视频,文章,动态,评论等,但是不应该是核心业务,不应该大量地请求MySQL数据库,给数据库造成大量的资源消耗,MySQL的数据库是非常宝贵的. 以某音为例,当我去搜索的时候,全抖音比较高的点赞数目应该是在1200w - 2000w,…
点赞

点赞业务比较频繁,很多人业务可能都会有这个,比如:博客,视频,文章,动态,评论等,但是不应该是核心业务,不应该大量地请求MySQL数据库,给数据库造成大量的资源消耗,MySQL的数据库是非常宝贵的.

以某音为例,当我去搜索的时候,全抖音比较高的点赞数目应该是在1200w - 2000w,我们自己的业务肯定答不到这么高的,但是假设有10个100w的点赞的博客,user_id为用户ID,publication_id为博客的id

  1. 第一种方式是直接操作数据库.每次有点赞或者取消点赞操作时,就更新MySQL数据库的点赞数.同时,插入或者更新一个user_id和publication_id的数据行,如果点赞操作非常频繁,会对数据库产生很大的压力.如果有大量的点赞记录,会对数据库产生很大的数据量,一篇文章,100w+的点赞的记录,对于MySQL来说,是非常恐怖的.

  2. 第二种方式是通过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
      

      image-20231105180611714

    • 判断一个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 + " 毫秒");}
      

      image-20231105180819204

      可以看到,其实对于时间来说,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 + " 毫秒");}
      

      image-20231105182159692

      但从时间来讲,只有一个字:快

    • 查询占用的内存的空间

      MEMORY USAGE  userId:114514:publication_id:738836
      

      image-20231105182354488

​ 其实可以看到,大概是占用66mb,如果用户的id为雪花算法的id,那可能占用的内存100mb

以上来说,主要还是一个bigkey的问题,如果点赞的数量过大,占用的内存过大,宝贵的内存不应该给这种业务.

  1. 自然而然,我们想到用非关系型数据库,但是不要是基于内存的,我想到的是用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,typelikedItemId字段创建一个唯一索引。

    db.collectionName.createIndex({ "userId": 1, "type": 1, "likedItemId": 1 },{ unique: true, name: "unique_index_name" }
    );
    

    详细解释:

    • collectionName:集合名称。
    • unique_index_name:你想要给索引起的名字,可以根据你的需求替换为其他名称。

    这个命令将在collectionName集合上创建一个名为unique_index_name的唯一索引,涵盖了userIdtypelikedItemId字段。 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.mzph.cn/news/173521.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【视觉SLAM十四讲学习笔记】第三讲——旋转向量和欧拉角

专栏系列文章如下: 【视觉SLAM十四讲学习笔记】第一讲——SLAM介绍 【视觉SLAM十四讲学习笔记】第二讲——初识SLAM 【视觉SLAM十四讲学习笔记】第三讲——旋转矩阵 【视觉SLAM十四讲学习笔记】第三讲——Eigen库 本章将介绍视觉SLAM的基本问题之一:如何…

Unity 自带的一些可以操控时间的属性或方法。

今天来总结下Unity自带的一些可以操控时间的方法。 1、Time.time。比较常用计算运行时间而触发特定事件。 public class Controller : MonoBehaviour {public float eventTime 5f; // 触发事件的时间private float startTime; // 游戏开始的时间private void Start(){startT…

计算机毕业设计|基于SpringBoot+MyBatis框架的电脑商城的设计与实现(用户资料修改)

计算机毕业设计|基于SpringBootMyBatis框架的电脑商城的设计与实现(用户资料修改) 该项目分析着重于设计和实现基于SpringBootMyBatis框架的电脑商城。首先,通过深入分析项目所需数据,包括用户、商品、商品类别、收藏、订单、购物…

【活动回顾】sCrypt在2023伦敦区块链大会上的精彩表现

2023伦敦区块链大会,是本年度最盛大的比特币及区块链行业活动。大会于2023年5月31日至6月2日,在伦敦女王伊丽莎白二世中心举行,旨在展示BSV区块链的真正潜力。 sCrypt Inc 的创始人兼 CEO 刘晓晖, 作为演讲嘉宾出席了会议。他向大…

掌握高效性能测试技能:JMeter基础入门!

一、JMeter基础 A、JMeter介绍 Apache JMeter是Apache组织开发的基于Java的压力测试工具。 Apache JMeter may be used to test performance both on static and dynamic resources (files, Servlets, Perl scripts, Java Objects, Data Bases and Queries, FTP Servers and …

【活动回顾】sCrypt在柏林B2029开发者周

B2029 是柏林的一个区块链爱好者、艺术家和建设者聚会,学习、讨论和共同构建比特币区块链地方。 在2023年6月9日至11日,举行了第7次Hello Metanet研讨会。本次研讨会旨在为参与者提供一个学习、讨论和共同构建比特币区块链的平台。 在这个充满激情和创意…

旋转框检测项目相关python库知识总结(mmrotate、ppyolo_r、yolov5_obb)

旋转框常用于检测带有角度信息的矩形框,即矩形框的宽和高不再与图像坐标轴平行。相较于水平矩形框,旋转矩形框一般包括更少的背景信息。旋转框检测常用于遥感等场景中,本博文简单的介绍了可应用于旋转框数据训练的开源库,数据结构…

SpringCloud 微服务全栈体系(十八)

第十一章 分布式搜索引擎 elasticsearch 八、RestClient 查询文档 文档的查询同样适用 RestHighLevelClient 对象,基本步骤包括: 准备 Request 对象准备请求参数发起请求解析响应 1. 快速入门 以 match_all 查询为例 1.1 发起查询请求 代码解读&…

数字技术-IPC专利分类号对应表

数字技术-IPC专利分类号对应表,基于2023年的关键数字技术专利分类体系,通过国际专利分类(IPC)号进行筛选。这些数据涵盖了各种数字技术领域的创新,包括但不限于人工智能、大数据、云计算、物联网、5G通信等。利用关键词…

538. 把二叉搜索树转换为累加树

538. 把二叉搜索树转换为累加树 题目: 给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。 提醒…

浅谈联网汽车安全漏洞

“智能网联汽车存在内生共性问题,即软硬件的漏洞后门,基于此进行的网络攻击可以直接带来勒索、盗窃、大规模车辆恶意操控风险,还有数据泄露等网络安全事件。如果内生的漏洞后门问题不解决,系统自身难保,很难谈系统安全…

QTextEdit多行富文本框控件

​锋哥原创的PyQt6视频教程: 2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~共计21条视频,包括:2024版 PyQt6 Python桌面开发 视频教程(无废话…

推荐你一个基于Koin, Ktor Paging等组件的KMM Compose Multiplatform项目

推荐你一个基于Koin, Ktor & Paging等组件的KMM Compose Multiplatform项目 Kotlin Multiplatform Mobile(KMM)已经从一个雄心勃勃的想法发展成为一个稳定而强大的框架,为开发人员提供了在多个平台上无缝共享代码的能力。通过最近的稳定…

跨境电商系统开发:开启全球贸易新纪元

随着全球电子商务的飞速发展,跨境电子商务已经成为了一种日益重要的贸易形式。跨境电商系统开发,为企业提供了全新的商业机遇,打开了全球贸易的新纪元。 跨境电商系统开发,旨在实现不同国家和地区之间的电子商务交易,促…

【机器学习】迁移学习

迁移学习:给定一个有标记的源域和一个无标记的目标域。这两个领域的数据分布不同。迁移学习的目的就是要借助源域的知识,来学习目标域的知识(标签)。或是指基于源域数据和目标域数据、源任务和目标任务之间的相似性,利用在源领域中学习到的知…

计算机毕业设计|基于SpringBoot+MyBatis框架的电脑商城的设计与实现(商品和购物车)

计算机毕业设计|基于SpringBootMyBatis框架的电脑商城的设计与实现(商品和购物车) 商品热销排行 1 商品-创建数据表 1.使用use命令先选中store数据库。 USE store;2.在store数据库中创建t_product数据表。 CREATE TABLE t_product (id int(20) NOT …

Git开发实用技巧

文章目录 一图胜千言:

SCI一区级 | Matlab实现GWO-CNN-LSTM-selfAttention多变量多步时间序列预测

SCI一区级 | Matlab实现GWO-CNN-LSTM-selfAttention多变量多步时间序列预测 目录 SCI一区级 | Matlab实现GWO-CNN-LSTM-selfAttention多变量多步时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现GWO-CNN-LSTM-selfAttention灰狼算法优化卷积长短…

介绍比特币上的 sCrypt 开发平台

最强大的基础设施和工具套件,可轻松构建和扩展您的 dApp 杀手级应用在哪里? 尽管比特币在小额支付、国际汇款和供应链管理等广泛用例中具有颠覆性潜力,但在推出 14 年后,我们还没有看到一款非常受欢迎并被主流采用的杀手级应用。 …

echart一键生成迁徙图

echart_move 介绍 echart迁徙图,选择起点和目的地生成迁徙图 软件架构 html echarts js 使用说明 将文件放到同一目录下打开index.html即可 默认是小飞机图标,如果想修改图标,将图片放到同一目录,如1.svg 代码修改为对应位…