如何设计一个点赞系统
首先我们定义出一个点赞系统需要对外提供哪些接口:
1.用户对特定的消息进行点赞;
2.用户查看自己发布的某条消息点赞数量以及被哪些人赞过;
3.用户查看自己给哪些消息点赞过;
这里假设每条消息都有一个message_id, 每一个用户都有一个user_id, 从以上三个接口我们可以大概想到需要在存储层保存哪些数据:
1.消息点赞表, 形式如{message_id, user_id, timestamp ... }
, 需要具备根据指定message_id 查找所有点赞人及点赞数量的能力;
2.用户点赞表,形式如{user_id, message_id, timestamp ... }
,需要具备根据user_id查找其所有点赞过的消息列表;
3.点赞计数表,形式如{message_id, count}
从以上几点来看,如果系统的用户规模不大比如用户小于1w人,如果用mysql来存储好像一张表就能搞定,用message_id做主键,然后在user_id上建立索引就可以很方便实现上面要求的三个接口:
select * from table where message_id=xxxx
select * from table where user_id=xxxxx
select count(*) from table where message_id=xxxx
但是如果用户数量很大比如向抖音这种过亿量级,单表行数量迅速膨胀,并且可能存在某些消息热门,短时间内大量用户点赞导致mysql挂掉(一般而言mysql能够支持的tps为10的三次级别,具体数值依赖与cpu 磁盘 内存性能)。
很自然我们想到分库分表,但是选择哪一个字段做分表列?如果选message_id 进行分库分表,那么如果要查询单个用户所有点赞的message, 就需要查询所有的库;反之用user_id进行分,那么查询指定message_id 查找所有点赞人就需要查询所有库;
从另一个方面来讲,上述方式构建表存在带量冗余信息(一条message 被1000人点赞, 那么就需要1000行来存储),这主要是收到mysql中关系型数据库模式的限制。
方案二:
上述方案在用户规模较大的情况下难以满足我们的需求,这里在提供一种以mogondb作为核心存储的可能方案。
mogondb与mysql不同,它天然支持分布式扩展并且他是无模式的,下面给出存储方案:
消息点赞表:
{"message_id":12345,"count": 3"user_List": [5555, 8888,9999 ....]
}
用户点赞表:
{"user_id":5555,"message_List": [12345...]
}
上面只列出核心字段,其他业务字段如时间戳等可以自行扩展;mogondb 可以对message_id 或者 user_id 进行索引查询,很方便的满足上面提出的三个接口。
这里还可以做一些特定的限制,如果一条消息被超过5000以上人点赞,那么我们是否有必要记录所有点赞过的用户呢?我个人觉得没有必要,不会有用户会去查询全量用户列表,因为假设客户端一屏幕展示20个点赞用户,那么5000/20=250,用户需要250此滑屏幕才能看完,不会有人这么干。
因此可以考虑,当点赞用户超过5000后,消息点赞表就只需要更新点赞数量,而不用将用户加到user_List列表里了。
但是如果某条消息上瞬间请求量大还是可能冲垮mogondb特定分片,从而导致服务不可用,如何解决呢?
这里我想到的是使用消息队列来削峰,具体的架构如下图所示:
https://docs.qq.com/flowchart-addon
用户点赞的流程:
1.首先业务网关层,这里提供身份校验、限流等通用能力;
2.业务逻辑层根据message id 进行哈希写入kafka分区;
3.消费者集群从kafka消费数据,写入mogondb;
如果是数据查询,那么业务逻辑层直接请求db拿到结果就可以返回;
以上就是我点赞系统的设计的一些思考。
相关文章:

如何设计一个点赞系统
首先我们定义出一个点赞系统需要对外提供哪些接口: 1.用户对特定的消息进行点赞; 2.用户查看自己发布的某条消息点赞数量以及被哪些人赞过; 3.用户查看自己给哪些消息点赞过; 这里假设每条消息都有一个message_id, 每一个用户都…...

对象存储测试工具-s3cmd
一、环境安装 官网:https://s3tools.org/s3cmd 下载安装包:https://s3tools.org/download GitHub:https://github.com/s3tools/s3cmd/releases 本文安装包:https://github.com/s3tools/s3cmd/releases/download/v2.0.2/s3cmd-2.0…...

OpenCV--图像色彩空间及转换
图像色彩空间及转换 python代码和笔记 python代码和笔记 import cv2 色彩空间,基础:RGB或BGR OpenCV中: 一、HSV(HSB):用的最多, Hue:色相-色彩(0-360),红色:0,绿色&…...

RIP解决不连续子网问题
#交换设备 RIP解决不连续子网问题 一、不连续子网的概念 相同主网下的子网,被另一个主网分割,例如下面实验拓扑在某公司的网络整改项目中,原先R1 和RS 属于同一主网络 10.0.0.0/8,现被 R2、R3、R4 分离,整网采用了 …...

动态轮换代理IP是什么?有什么用?
如果您要处理多个在线帐户,选择正确的代理类型对于实现流畅的性能至关重要。但最适合这项工作的代理类型是什么? 为了更好地管理不同平台上的多个账户并优化成本,动态住宅代理IP通常作用在此。 一、什么是轮换代理? 轮换代理充当…...

MAC配置VScode中C++项目debug环境
文章目录 配置步骤问题解决Unable to start debugging. LLDB exited unexpectedly with exit code 137 (0x89). 配置步骤 在Mac上配置VS Code以进行C调试涉及几个步骤: 安装必要的工具: 确保您已经安装了Visual Studio Code和C插件。 检查是否安装了Clang…...

PostgreSQL源码分析——CREATE CAST
CREATE CAST源码分析 CREATE CAST用法 CREATE CAST —— 定义一个用户自定义的类型转换 用法如下: CREATE CAST (source_type AS target_type)WITH FUNCTION function_name [ (argument_type [, ...]) ][ AS ASSIGNMENT | AS IMPLICIT ]CREATE CAST (source_type…...

解锁5G新营销:视频短信的优势与全方位推广策略
随着5G时代的全面来临,企业的数字化转型步伐日益加快,视频短信作为新兴的数字营销工具,正逐步展现出其巨大的潜力。视频短信群发以其独特的形式和内容,将图片、文字、视频、声音融为一体,为用户带来全新的直观感受&…...

视频监控平台功能:国外的硬盘录像机NVR通过ISUP协议(原ehome协议)接入AS-V1000视频平台
目录 一、背景说明 二、ISUP协议介绍 1、海康ISUP协议概述 2、ISUP协议支持主码流和子码流切换 (1)灵活配置和个性化 (2)适应不同网络带宽,提高使用体验 3、海康ehome相关文章 三、ISUP协议接入说明 1、平台侧…...

PostgreSQL查询用户
在 PostgreSQL 中,可以通过查询系统表来确定当前用户是否是超级管理员(超级用户)。具体来说,可以使用 pg_roles 系统表,该表包含数据库中所有角色的信息。 以下是查询当前用户是否是超级用户的 SQL 语句: …...

力扣1539.第k个缺失的正整数
力扣1539.第k个缺失的正整数 占位运算 只要n<k ,k;最终k就是结果 class Solution {public:int findKthPositive(vector<int>& arr, int k) {for(int n : arr){if(n < k) k ;else break;}return k;}};...

如何快速解决屏幕适配问题
下面将利用postcss插件快速解决屏幕适配问题。仅用少量代码,新手均可快速使用。 Step1. 安装 npm install postcss-px-to-viewport-8-plugin --save-dev Step2. 新建 postcss.config.js 文件,做基础配置 module.exports {plugins: {postcss-px-to-v…...

Go基础编程 - 09 - 通道(channel)
通道(channel) 1. 声明2. channel的操作3. 无缓冲通道4. 有缓冲通道5. 如何优雅的从通道循环取值6. 单向通道7. 异常总结 上一篇:结构体 Go语言的并发模式:不要通过共享内存来通信,而应该通过通信来共享内存。 Go语言…...

[SAP ABAP] 数据类型
1.基本数据类型 示例1 默认定义的基本数据类型是CHAR数据类型 输出结果: 示例2 STRING数据类型用于存储任何长度可变的字符串 输出结果: 示例3 DATE数据类型用于存储日期信息,并且可以存储8位数字 输出结果: 提示Tips:日期和时间类型的变量可以直接进…...

什么是Vue开发技术
概述 Vue.js 是一个用于构建用户界面的渐进式框架,它设计得非常灵活,可以轻松地被集成到任何项目中。 vue是视图的发音,其目的是帮助开发者易于上手,提供强大的功能构建复杂的应用程序 示例 以下是vue基本的语法概述 声明式渲…...

【QT】
通信服务端实现 widget.h文件 #ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QTcpServer>//服务器类 #include <QMessageBox>//消息 #include <QTcpServer> #include <QList> #include <QTcpSocket> QT_BEGIN_NAMESPAC…...

【转载】使用 .NET Upgrade Assistant(升级助手)升级 .NET 老旧版本项目
使用 .NET Upgrade Assistant(升级助手)升级 .NET 老旧版本项目:https://blog.csdn.net/ChaITSimpleLove/article/details/134711604...

SpringBoot如何自定义启动Banner 以及自定义启动项目控制台输出信息 类似于若依启动大佛 制作教程
前言 Spring Boot 项目启动时会在控制台打印出一个 banner,下面演示如何定制这个 banner。 若依也会有相应的启动动画 _ooOoo_o8888888o88" . "88(| -_- |)O\ /O____/---\____. \\| |// ./ \\||| : |||// \/ _||||| -:- |||||- \| | \\…...

访问控制列表(Access Control Lists,ACL)与哈希查找的爱恨情怨
访问控制列表(Access Control Lists,ACL)与哈希查找 什么是访问控制列表ACL?直接说ACL是干啥的ACL概念为什么需要ACLACL类型ACL匹配机制使用例子 哈希查找什么是哈希查找?哈希查找的基本原理哈希查找的步骤 哈希查找在…...

一文讲清楚分销裂变是什么?怎么做好分销裂变?【附案例】
在数字化营销日益盛行的今天,分销裂变作为一种高效的推广手段,受到了越来越多企业的青睐。那么,分销裂变究竟是什么?我们又该如何做好分销裂变呢?林叔将从定义、方法以及案例分析三个方面进行阐述。 一、分销裂变是什…...

Mybatis Plus 详解 IService、BaseMapper、自动填充、分页查询功能
结构直接看目录 前言 MyBatis-Plus 是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。 愿景 我们的愿景是成为 MyBatis 最好的搭档,就像 魂斗罗 中的 1P、2P,基友搭配,效…...

鸿蒙开发组件:【FA模型的Context】
FA模型的Context FA模型下只有一个Context。Context中的所有功能都是通过方法来提供的,它提供了一些featureAbility中不存在的方法,相当于featureAbility的一个扩展和补全。 接口说明 FA模型下使用Context,需要通过featureAbility下的接口…...

Linux下手动修改服务器时间(没网环境下)
在客户服务器上更新程序时,发现服务器时间不对,现在应该是下午13:44:00,但服务器却显示为:21:40:53,所有是不对的。 date解决办法: 1、由于服务器是没有网的,只能手动设置时间,输入…...

嵌入式系统软件开发环境_3.主要功能和典型产品
1.嵌入式系统软件开发环境的主要功能 由于嵌入式系统的软件开发通常采用的是交叉开发方式,因此其开发环境中的工具应支持这种交叉开发的特点。嵌入式系统软件开发环境的功能应覆盖嵌入式软件开发过程,即编码过程、编译过程、构建过程、下载过程、调式过程…...

使用Python保护或加密Excel文件的7种方法
目录 安装Python Excel库 Python 使用文档打开密码保护 Excel 文件 Python 使用文档修改密码保护 Excel 文件 Python 将 Excel 文件标记为最终版本 Python 保护 Excel 工作表 Python 在保护 Excel 工作表的同时允许编辑某些单元格 Python 锁定 Excel 工作表中的特定单元…...

【嵌入式Linux】<总览> 文件IO(更新中)
文章目录 前言 一、常用函数 1. open函数 2. close函数 3. write函数 4. read函数 5. dup函数 6. dup2函数 二、文件读写细节 1. 换行符 2. 文件描述符 3. errno和perror 前言 在Linux系统中,一切皆文件。因此,掌握Linux下文件IO常用的函数…...

【无线传感网】分簇路由算法介绍
目录 1、LEACH路由算法 2、PEGASIS 算法 3、TEEN 算法 5、APTEEN 5、LEACH-C 算法 无线传感网中的路由协议就是寻找一条路径让网络中节点沿着这条路径将数据信息传输出去。路由协议的两大关键要点就是路径的优化和数据的分组,在传统计算机网络中,是将网络的拓扑…...

java 利用poi读取wps嵌入式图片,自测
代码 主要工具类 需要引入依赖: package com.chenkang.demo.util;import cn.wps.officeDocument.x2017.etCustomData.CellImagesDocument; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.…...

git 常用操作指令
文章目录 git clonegit configgit addgit commitgit rmgit branch/checkoutgit pull/pushgit rebash/merge git clone git clone 可以将一个远程 Git 仓库拷贝到本地,让自己能够查看该项目,或者进行修改。 拷贝项目命令格式如下:git clone [u…...

达梦导入导出
针对导出数据库表结构通常有 3 种方法: 使用 DTS 导出 打开 DTS 迁移工具,选择【DM-->SQL】并链接到数据库中,如下图所示: 添加定义脚本,并选择【迁移范围】(仅迁移对象定义),如…...