【问题标题】:Database design for email-style application电子邮件式应用程序的数据库设计
【发布时间】:2011-08-26 17:46:30
【问题描述】:

我正在寻找一些关于如何为电子邮件风格的应用程序设计数据库的建议,特别是如何处理向多个用户发送消息以及显示哪些消息发送给了哪些用户。

这是我目前所拥有的:

消息(主键为 Id)

  • Id(身份)
  • SenderId(Users.Id 的外键)

ReceivedMessages(主键为 MessageId + RecipientId)

  • MessageId(Messages.Id 的外键)
  • RecipientId(Users.Id 的外键)
  • IsRead

因此,对于发送的每条消息,Messages 中都会有一行包含数据,然后 ReceivedMessages 中的每个接收者都有一行。

但是,如果我想查看用户发送的所有消息,以及这些消息是发送给谁的,该怎么办?对于每条消息,我需要找到该消息的所有 ReceivedMessages 行,并将所有这些行与用户表连接起来,然后以某种方式连接所有名称(如下所示:Concatenate many rows into a single text string?)。这可能会导致扩展问题,还是真的没什么好担心的?

有什么想法/建议吗?谢谢。

【问题讨论】:

    标签: sql database email


    【解决方案1】:

    我认为您的设计没有问题,并且不会预料到在您的表上正确索引会出现可伸缩性问题(除非您谈论的是大规模,例如 gmail、Yahoo 邮件等)。

    至于连接收件人姓名,我建议您在应用程序端而不是在 SQL 中执行此操作,或者确定您是否需要这样做(您可能希望显示一个列表而不是连接的字符串) .

    【讨论】:

      【解决方案2】:

      用户发送的所有消息,以及发送给谁

      您可以将其作为聚合查询来执行,例如:

      SELECT u1.user_name, m.message, GROUP_CONCAT(DISTINCT u2.user_name)
      FROM messages m JOIN users u1 ON (m.senderID=u1.user_id)
                      JOIN receivedmessages r ON (m.id=r.messageId)
                      JOIN users u2 ON (r.RecipientId=u2.user_id)
      GROUP BY u1.user_name, m.message;
      

      但由于收件人本质上是无限的,您可能会遇到 GROUP_CONCAT 的字符串长度限制。

      因此,最好进行非聚合选择并处理记录以显示在您的应用程序层中:

      SELECT u1.user_name, m.message, DISTINCT u2.user_name
      FROM messages m JOIN users u1 ON (m.senderID=u1.user_id)
                      JOIN receivedmessages r ON (m.id=r.messageId)
                      JOIN users u2 ON (r.RecipientId=u2.user_id)
      ORDER BY u1.user_name, m.sent_date, u2.user_name;
      

      【讨论】:

        【解决方案3】:

        用户更改姓名和电子邮件,但不更改登录名。考虑模仿基于 unix 的邮箱(例如 pine)中发生的事情:

        received_messages (
          user_id,
          message_id,
          message_date,
          message_title,
          message_content,
          message_sender,
          message_recipient,
          message_is_read
        )
        

        sent_messages 相同,即每个用户有两个“文件”。

        或者甚至将后两者与发送/接收标志合并。

        【讨论】:

          【解决方案4】:

          我面临着为网站创建电子邮件或消息传递系统的相同挑战...你们忘记了一件事...IsRead、IsDraft、IsFlagged、IsReply、IsTrash 等...需要单独表,因为同一消息将被两个或更多人标记、阅读或未阅读!所以,我们必须有一个如下所示的状态表...

          StatusID    int     
          MessageID   int  
          MemberID    int  
          DateTime    datetime    
          IPAddress   varchar(65)  
          IsRead  char(1)   
          IsDraft char(1)  
          IsFlagged   char(1)   
          IsForwarded char(1)  
          IsReply char(1)  
          IsTrash char(1) 
          

          除了成员表或用户表之外,您至少需要三个表:

          mail  
          folders  
          status  
          attachment  
          log  
          

          如果这是针对现有网站...如果您希望该邮件系统有很多活动,我会将邮件系统分离到一个单独的数据库中。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-02-07
            • 2014-12-01
            • 2013-12-19
            • 1970-01-01
            • 2015-11-03
            • 1970-01-01
            • 1970-01-01
            • 2018-01-10
            相关资源
            最近更新 更多