将用户与消息连接起来的数据库设计困境

时间:2014-12-17 18:23:46

标签: mysql database database-design foreign-keys relational-database

这是我想出的,但我不确定其中哪一个是最好的"。也许还有另一个,我可能不知道的更好的一个。请注意,我的应用中既有收件箱又有发件箱,发件人或收件人删除的邮件仍然可供其他相关用户看到,除非他们自己将其删除。

选项1 - 简单ManyToMany:
表:
用户 - 只是用户字段
消息 - 只是消息字段
User_Message - 包含2个外键:user_id和message_id

示例:当用户发送消息时,将一条消息行添加到Message表中,并将两行添加到User_Message,显然将发件人和收件人与添加的消息连接起来。
现在,这可能会得到一些当我们想要仅获取收件箱邮件时会出现问题,因为ManyToMany将获取所有邮件,因此我提出了选项2.

选项2 - OneToMany:
表:
用户 - 只是用户字段
MessageReceived - 消息字段和user_id的外键
MessageSent - 消息字段和user_id的外键

示例:当用户发送消息时,此消息将添加到已接收和已发送的表中,但具有不同的user_id。当然发件人ID将在收到的表中发送表和收件人ID 现在,当我只想获取收件箱邮件时,我从MessageReceived表中获取邮件,并在删除例如收件箱(MessageReceived)邮件时,它的副本仍然保留在MessageSent中并且可供发件人使用,所以一切都很好,但是我觉得有什么东西"不冷静"关于这个,因为我基本上在两个表中保持ALMOST相同的数据。

请让我知道您对此有何看法,如果有更好的方法,我也会倾听。谢谢您的时间。

编辑:
Madbreaks Tab Alleman 都提供了非常好的和有些类似的解决方案,所以非常感谢。我会选择Madbreaks,因为我更喜欢删除连接表中的关系,而不是删除'删除'专栏,但这只是我的口味。不过,谢谢你的时间和答案。

2 个答案:

答案 0 :(得分:2)

对于每封邮件,您不需要在user_messages中添加2行 - 该表中有3列:sender_idrecipient_idmessage_id

修改

您在下面的问题中描述的删除方案会改变一些事情。您可能现在有两个1对n关系,而不是n对n方法:

  1. 发件人与其众多已发送邮件之间的关系
  2. 收件人与收到的许多邮件之间的关系
  3. 我可能会让messages表有一个发件人ID外键。然后我会有一个message_recipients表,用于将用户(收件人)ID映射到消息ID。

    现在,如果发件人可以删除邮件但收件人仍然可以访问它(并知道发件人是谁),那么您将需要四个表:

    1. 用户
    2. 消息
    3. message_sender(1对1地图) - 删除已发送消息的发件人从
    4. 删除
    5. message_recipients(1对n映射) - 删除收到的邮件的收件人从此处删除
    6. 从您的问题不清楚这是否是一项要求,我只是为了完整性而添加它。您可能需要触发器或后续查询来确定是否/何时用户和消息表之间没有剩余关系,并且此时(可能)删除消息本身。

答案 1 :(得分:2)

这就是我要做的事情(我假设一条消息只能有一个发件人,但有多个收件人)

  • UserTable - 包含UserID和其他信息
  • MessageTable - 具有MessageID,SenderID(FK到UserTable.UserID)和其他信息
  • MessageRecipientsTable - 具有MessageID,RecipientID(FK到UserTable.UserID),以及可能的其他信息,例如何时/如果收到,等等。

如果您希望收件人能够删除邮件并仍然为发件人(和其他收件人)显示该邮件,那么您应该向MessageRecipientsTable添加“已删除”列。您永远不会从消息表中删除行,但在填充收件人收件箱时,您将过滤掉“已删除”为真的行。