Database design 针对不同类别类型的讨论系统的最佳数据库设计?

Database design 针对不同类别类型的讨论系统的最佳数据库设计?,database-design,messaging,Database Design,Messaging,我想为可能属于单个用户或用户组的邮件设计一个邮件收件箱表模式 假设我们已经有了这些表: 具有uid(主键)的用户表 带有gid(主键)的组表 组\具有gid(FK)和uid(FK)的U关联表 那么,为了满足这些要求,消息和消息发布表的最佳设计是什么 任何个人用户都可以向其他用户发送消息 任何单个用户都可以向多个用户发送消息 任何单个用户都可以向单个组中的所有用户发送消息(特定组中的用户数可能随时间而变化) 您应该能够查询属于特定用户的所有邮件 我目前的想法是: 设置三个表: 带mid(

我想为可能属于单个用户或用户组的邮件设计一个邮件收件箱表模式

假设我们已经有了这些表:

  • 具有uid(主键)的用户表
  • 带有gid(主键)的组表
  • 组\具有gid(FK)和uid(FK)的U关联表
那么,为了满足这些要求,消息和消息发布表的最佳设计是什么

  • 任何个人用户都可以向其他用户发送消息
  • 任何单个用户都可以向多个用户发送消息
  • 任何单个用户都可以向单个组中的所有用户发送消息(特定组中的用户数可能随时间而变化)
  • 您应该能够查询属于特定用户的所有邮件
我目前的想法是:

  • 设置三个表:
    • 带mid(主键)的消息,让我们说出主题
    • 具有mpmid(FK)、mptype ENUM(“用户”、“组”)和mpid(FK)的消息\u参与者 (类型)
    • msgmid(FK)引用消息表PK的消息发布
  • 获取所有消息
    • 获取特定用户的所有组
    • 查询消息\u参与者,其中(mptype='user'和mpid=uid)或(mptype='group'和mpid-IN(所有用户组))
  • 这样,您甚至可以同时向单个用户和组发送消息


    这就是您通常处理此类问题的方式吗?

    这是一个好问题。听起来你走对了方向。我的做法如下:

    表:

    • 消息带有id、用户id、主题
    • 消息用户具有id(主键)、消息id(FK)、用户id(FK)
    • 具有id(主键)、消息id(FK)的消息组
    现在举个例子:假设一个用户向一个组发送一条消息,在消息组中插入一行,然后在消息组中为组中的每个成员插入一行。这允许您捕获发送消息的组以及当时接收消息的用户。用户可以在过去或将来从组中添加或删除,因此您必须记录发送邮件时组中的每个用户。你不可能只录下这群人

    要获取用户的所有消息,请执行以下操作:

    从消息中选择* 内部连接消息\u用户 ON message.id=message\u users.message\u id 其中message_users.user_id={user_id}

    还要确保您使用的字段不能引用多种类型的主键。消息参与者表中的mpid字段不应同时引用用户和组


    不知道你为什么需要帖子。邮件是否有多个帖子?希望这有帮助。

    詹姆斯说得对

    还要确保您使用的字段不能引用多种类型的主键。消息参与者表中的mpid字段不应同时引用用户和组

    重载外键列始终是一种糟糕的设计,会导致数据完整性差和其他问题

    如果您的目标是拥有“临时收件人”——也就是说,如果我今天加入一个组,我会立即看到昨天发送给该组的所有邮件——那么您的模型就接近了。将收件人描述为“参与者”用词不恰当,但我将按以下方式处理这个问题

    TABLE MessageRecipients
    (
      Message_Id INT NOT NULL
        CONSTRAINT FK__MessagesRecipients__Messages
        FOREIGN KEY (Message_Id) REFERENCES Messages (Message_Id),
    
      RecipientType_Code CHAR(1) NOT NULL
        CONSTRAINT CK__MessageRecipients__RecipientType_Code_Domain
        CHECK RecipientType_Code IN ('U','G'),
    
      User_Id NULL
        CONSTRAINT FK__MessagesRecipients__Users
        FOREIGN KEY (User_Id) REFERENCES Users (User_Id),
    
      Group_Id NULL
        CONSTRAINT FK__MessagesRecipients__Groups
        FOREIGN KEY (Group_Id) REFERENCES Groups (Group_Id),
    
      CONSTRAINT CK__MessageRecipients__RecipientType_Validity
        CHECK (RecipientType_Code = 'U' AND User_Id IS NOT NULL AND Group_Id IS NULL)
           OR (RecipientType_Code = 'G' AND User_Id IS NULL AND Group_Id IS NOT NULL)
    
    )
    

    否则,如果您希望消息与用户绑定,而不考虑组成员身份(即,如果我删除了一个组,我仍然可以看到来自该组的消息),那么我建议James的方法。

    为什么消息属于用户组?为什么不复制邮件并将其发送给组中的每个成员?您的请求是否声明消息必须属于某个组?只是好奇。好吧,如果我要向每个组成员发送一条单独的消息,那么如果该用户回复该消息,您就必须将其发送给该组的所有成员,依此类推。因此,我想一定有更好的方法可以只存储消息的一个副本。我想你可能会有另一个表,将个人帖子与用户链接起来,这个表可能会包含另一列关于该消息是否已被某个特定用户阅读或删除的信息……谢谢你的回答。不使用列作为多个主键是正确的。您在创建消息时插入每个单独用户的方法一开始并不想这样做,但随着我的深入思考,这似乎是最合理的做法,因为加入组的新用户不需要在加入组之前查看创建的消息。我提到POSTS表是因为每条消息都可以在初始消息上有“参与者”的评论。我想我应该称之为某种“讨论”…谢谢Alex,你的方法也值得考虑。正如我在上面的评论中提到的,我会坚持新用户加入一个没有看到旧消息的群组。。。同意术语不太简洁。