站内群发消息三种不同用户量的数据库设计

 更新时间:2023年12月02日 08:47:03   投稿:yin  
很多SNS网站和一部分CMS网站都广泛地应用了站内信这一模块,这个看似简单的东西其实背后隐藏着很多需要设计师重视的设计细节,要做好这个“邮递员”是很不容易的,本文讲述站内群发消息三种不同用户量的数据库设计,逐渐设计一个百万级用户量的站内信群发数据库

随着WEB2.0的发展,用户之间的信息交互也变得十分庞大,而且实时性要求越来越高。现在很多SNS网站和一部分CMS网站都广泛地应用了站内信这一模块,这个看似简单的东西其实背后隐藏着很多需要设计师重视的设计细节,要做好这个“邮递员”是很不容易的。本文讲述站内群发消息三种不同用户量的数据库设计,逐渐设计一个百万级用户量的站内信群发数据库,看完以后你就会明白什么是真正可靠高效的“邮递员”。

1、几十——几百的用户量

这样的网站规模最小,可能是一个中小企业的CMS系统,面对这样的用户量,我们就不必要考虑短消息数据量太大的问题了,所以按照怎么方便怎么来的原则,群发就每人复制一条消息数据,这样用户可以自己管理自己的消息,可以非常方便进行“已读、未读、删除”等操作。按照这个思路,我们的数据库设计如下:

表T_Message

1

2

3

4

5

6

Id            bigint      --消息ID

SenderId      bigint      --发送者ID

ReceiverId    bigint      --接收者ID

SendTime      datetime    --发送时间

ReadFlag      tinyint     --已读标志

MessageText   text        --消息正文

这样,我们接受自己的消息时只要做如下查询:

1

SELECT * FROM T_Message WHERE ReceiverId=myid

查询自己的未读消息只要做如下查询:

1

SELECT * FROM T_Message WHERE ReceiverId=myid and ReadFlag=0

这种方法很简单,可能是我们第一个想到的,对于这样的用户量的情况这样的设计确实也足够了。

2、几千——几万的用户量

用户量到了这样的级哦别,这个网站应该算是比较大了,笔者估计,可能是一个地区性的SNS网站。那么面对这样的用户量,我们又该如何来设计站内信群发呢?上面第一种思路还行得通吗?应该这样说,如果勉强要用上面那种设计,也是可以的,只不过T_Message可能要考虑分区。但是,大家会不会觉得消息正文复制那么多条对于这样的用户量来讲空间浪费太大,因为考虑到接收者一般是不修改消息正文的,所以我们可以让所有接收者共享一条消息正文。具体数据库设计方法和上面大同小异:

T_Message

1

2

3

4

5

6

Id              bigint      --消息ID

SenderId        bigint      --发送者ID

ReceiverId      bigint      --接收者ID

SendTime        datetime    --发送时间

ReadFlag        tinyint     --已读标志

MessageTextId   bigint      --这里把消息正文内容换成消息正文Id

T_MessageText

1

2

3

Id              bigint      --ID标识

SenderId        bigint      --发送者ID

MessageText     text        --消息正文

这样,我们就大大节省了消息的存储空间,但是查询的时候就稍微麻烦一点,就需要进行联合查询了,查询自己的未读消息可以这样(意思一下,可能还有更高效的查询方式):

1

2

3

SELECT T_Message.*,T_MessageText.* FROM T_Message

INNER JOIN T_MessageText ON T_Message.MessageTextId=T_MessageText.Id

WHERE T_Message.ReceiverId=myid AND T_Message.ReadFlag=0

用这种方法除了正文我们不能随便删除外,用户还是可以自己管理自己的消息。

3、百万级大用户量

如果一个网站到了百万级的用户量了,那我不得不膜拜该网站和网站经营者了,因为经营这样的网站一直是笔者的梦想:)好了,回归正题,如果这样的系统放你面前,让你设计一个站内信群发数据库,你该何去何从,总之,上面两种常规的办法肯定是行不通了的,因为庞大的数据量会让消息表撑爆,即使你分区也无济于事。这时候作为一个系统架构师的你,可能不仅仅要从技术的角度去考虑这个问题,更要从用户实际情况去着手寻找解决问题的办法。这里,有一个概念叫“活跃用户”,即经常登录网站的用户,相对于那些一时冲动注册而接下来又从来不登录的用户来说,活跃用户对网站的忠诚度很高,从商业的角度来讲,忠诚的客户享受更高端的服务。

根据这个思路,我们来探索一种方法。假设网站有500万注册用户,其中活跃用户为60万(这个比例真很不错了),现在我们要对所有用户群发一封致谢信。还是上面两张表,首先我们可以先往消息表中插入一条群发标识为-1的消息,这里我们用字段SourceMessageId(原始消息)来标识(-1为原始群发消息本身,其他则是原始消息id),这样其实群发的工作已经完成了,用户可以看到这条公共的消息了。但是用户需要有消息的控制权,所以必须让每个用户拥有一条自己的消息。要达到这个目的,我们可以让用户登录时检查是否已经拷贝原始消息,如果没有拷贝,则拷贝一份原始消息并插入消息表,群发标识为原始消息的id;如果已经存在原始消息的拷贝,则什么都不做。这样,我们就只要为这60万活跃用户消耗消息空间就可以了。具体数据库设计如下:

T_Message

1

2

3

4

5

6

7

Id                  bigint      --消息ID

SenderId            bigint      --发送者ID

ReceiverId          bigint      --接收者ID,如果为原始群发消息则为-1

SendTime            datetime    --发送时间

ReadFlag            tinyint     --已读标志,如果为原始群发消息则统一为0未读

SourceMessageId     bigint      --如果为-1则为原始群发消息,其他则为原始消息id

MessageTextId       bigint      --这里把消息正文内容换成消息正文Id

T_MessageText与上面方法的一样。

当然,如果你的活跃用户达到100%,那这种方法相对前一种就没有优势了,但这种情况基本上不太可能,所以,笔者觉得这种方法来处理大用户量的消息群发还是可行的。

4、总结

本文只是大致阐述了实现的原理,很多细节都忽略没有考虑,纯粹一个设计想法而已,有兴趣的朋友可以去自己实践一下,另外,笔者对数据库也不是很精通,如果有哪里阐述错误的还请指出,让我们一起进步。

到此这篇关于站内群发消息三种不同用户量的数据库设计的文章就介绍到这了,更多相关站内群发消息的数据库设计内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • dapper使用Insert或update时部分字段不映射到数据库

    dapper使用Insert或update时部分字段不映射到数据库

    我们在使用dapper的insert或update方法时可能会遇见一些实体中存在的字段但是,数据库中不存在的字段,这样在使用insert时就是抛出异常提示字段不存在,这个时候该怎么解决呢,下面给大家分享示例实体代码,感兴趣的朋友一起看看吧
    2023-12-12
  • Dbeaver连接ClickHouse全过程

    Dbeaver连接ClickHouse全过程

    文章主要介绍了如何使用Dbeaver连接ClickHouse数据库,首先需要安装Dbeaver工具,然后通过新建驱动管理器和设置库信息来配置驱动,接着,创建数据库连接并填写连接配置信息,测试连接以确保配置正确,最后,成功连接ClickHouse数据库
    2024-11-11
  • 在PostgreSQL的基础上创建一个MongoDB的副本的教程

    在PostgreSQL的基础上创建一个MongoDB的副本的教程

    这篇文章主要介绍了在PostgreSQL的基础上创建一个MongoDB的副本的教程,使在使用NoSQL的同时又能用到PostgreSQL中的东西,需要的朋友可以参考下
    2015-04-04
  • 数据库触发器Trigger详解

    数据库触发器Trigger详解

    在数据库管理系统中,触发器(Trigger)是一种特殊的存储过程,它在特定的事件发生时自动执行,本文给大家介绍数据库触发器Trigger的相关知识,感兴趣的朋友一起看看吧
    2025-05-05
  • 免费开源数据库:SQLite、MySQL和PostgreSQL的优缺点

    免费开源数据库:SQLite、MySQL和PostgreSQL的优缺点

    对于处理大规模数据和高并发访问的场景,MySQL和PostgreSQL更适合,SQLite在小型应用程序或嵌入式设备中是一种轻量级、简单和易于使用的选择,根据具体的应用需求和场景特点,选择合适的开源关系型数据库可以提供更好的性能、可扩展性和灵活性
    2024-02-02
  • Window下Neo4j安装图文教程

    Window下Neo4j安装图文教程

    这篇文章主要为大家详细介绍了Window下Neo4j安装图文教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-04-04
  • 数据库分库分表是什么,什么情况下需要用分库分表

    数据库分库分表是什么,什么情况下需要用分库分表

    这篇文章主要介绍了数据库分库分表是什么,什么情况下需要用分库分表,需要的朋友可以参考下
    2021-03-03
  • 利用带关联子查询Update语句更新数据的方法

    利用带关联子查询Update语句更新数据的方法

    这篇文章主要介绍了利用带关联子查询Update语句更新数据的方法,需要的朋友可以参考下
    2014-08-08
  • 8种主流NoSQL数据库系统特性对比和最佳应用场景

    8种主流NoSQL数据库系统特性对比和最佳应用场景

    这篇文章主要介绍了8种主流NoSQL数据库系统特性对比和最佳应用场景,对选择一个NoSQL数据库来说是一个不错的参考文章,需要的朋友可以参考下
    2014-06-06
  • 数据库中union 与union all 的区别

    数据库中union 与union all 的区别

    当我们要对两个或两个以上的表进行操作时。我们经常会用到union 与union all
    2009-11-11

最新评论