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

Ser*_*iuk 5 mysql sql database database-design scalability

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

用户(user_id)

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

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

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

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

用户(user_id)

Sent_messages(sent_id,sender_id(引用user_id),主题,正文)

Received_messages(sent_id,receiver_id(引用user_id),主题,正文)

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

这种方法导致

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

所以这里提出问题:

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

谢谢!

PS我明白,在解决这些可伸缩性问题之前,网站必须非常成功,但我想知道如果需要该怎么做.

UPDATE

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

Dan*_*llo 3

在将邮件发送给多个收件人的情况下,您可能希望避免多次复制邮件正文。这是您可能需要考虑的另一个选择:

  • 用户(user_id)

  • 消息(message_id、sender_id、主题、正文)

  • receive_messages(message_id、user_id、address_mode、已删除)

这种模式可能更像 Twitter,而不是电子邮件,但它可能有一些优点。

规则是:

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

以下是一些优点:

  • 这比原始问题中提到的两个选项占用的空间更少,特别是如果用户通常将消息发送给多个收件人。
  • 由于消息永远不会重复,因此更容易缓存消息表。
  • 删除邮件的收件人不会删除该邮件发送给该用户的信息。它将在 receive_messages 表中简单地标记为“已删除”。
  • 而且您还会得到一个标准化模型。

对于大多数应用程序,如果您对上述模型使用乐观隔离级别,即使您期望以每秒几个的速率交换消息,也不应该出现性能问题。另一方面,如果您预计每秒有数百或数千条消息,那么可能确实需要考虑其他选项。