可扩展的MySQL数据库,用于类似邮件的消息

假设我们有一个受欢迎的网站.我们需要在用户之间实现类似邮件的消息传递.
典型的解决方案是使用2个表:

用户(user_id)

消息(message_id,sender_id(引用user_id),receiver_id(引用user_id),主题,正文).

该方法有2个显着的局限性

>所有用户的所有消息都存储在一个表中,导致其高负载并降低整体数据库性能.
>当有人需要同时向多个用户发送消息时,会复制该消息(recipients_count)次.

另一个解决方案使用3个表:

用户(USER_ID)

Sent_messages(sent_id,正文)

Received_messages(sent_id,正文)

received_messages的主题和正文从sent_messages的相应字段中复制.

这种方法导致

>通过将信息从一个表复制到另一个表来对数据库进行非规范化
>用户实际上可以删除发送/接收的消息,而无需从接收器/发送器中删除它们.
>消息占用的空间大约是2倍
>每张表的装载量减少约2倍.

所以这里提出问题:

>考虑到哪种设计更适合高负载和可扩展性? (我认为这是第二个)
>是否有其他数据库设计可以处理高负载?它是什么?有什么限制?

谢谢!

附:我知道在解决这些可扩展性问题之前,网站必须非常成功,但我想知道如果需要该怎么做.

UPDATE

目前,对于第一个版本,我将使用Daniel Vassallo提出的设计.但如果将来一切正常,设计将改为第二个.感谢Evert减轻了我的担忧.

最佳答案
在向多个收件人发送邮件的情况下,您可能希望避免多次复制邮件正文.这是您可能需要考虑的另一个选项:

  • users (user_id)

  • messages (message_id,sender_id,subject,
    body)

  • received_messages (message_id,user_id,address_mode,deleted)

这种模式可能比电子邮件更像推特,但它可能带来一些优势.

规则是:

>消息只能由一个用户发送,在每条消息的sender_id中引用.
>每个收件人都将在received_messages表中定义. address_mode字段可以定义消息是直接发送给收件人,还是作为CC发送,还是作为BCC发送.该字段显然是可选的.
>收件人删除的邮件将在received_messages表中标记已删除的标志.
>转发和回复的邮件需要使用新的sender_id重新创建.然后可以修改消息正文.

这些是一些优点:

>这比原始问题中提到的两个选项占用的空间更少,特别是如果用户通常会向多个收件人发送邮件.
>更容易缓存消息表,因为消息永远不会重复.
>删除邮件的收件人不会删除邮件发送给该用户的信息.它只会在received_messages表中标记为“已删除”.
>你还得到一个标准化的模型.

对于大多数应用程序,如果对上述模型使用乐观隔离级别,即使您希望以每秒几个的速率交换消息,也不应该存在性能问题.另一方面,如果您期望每秒有数百或数千条消息,那么考虑其他选项可能就是这种情况.

相关文章

在正式开始之前,我们先来看下 MySQL 服务器的配置和版本号信...
> [合辑地址:MySQL全面瓦解](https://www.cnblogs.c...
物理服务机的CPU、内存、存储设备、连接数等资源有限,某个时...
1 回顾 上一节我们详细讲解了如何对数据库进行分区操作,包括...
navicat查看某个表的所有字段的详细信息 navicat设计表只能一...
文章浏览阅读4.3k次。转载请把头部出处链接和尾部二维码一起...