我想为可能属于个人用户或用户组的邮件设计邮件收件箱表架构。
假设我们已经有了这些表格:
然后,满足这些要求的消息和消息发布表的最佳设计是什么:
我目前的想法是:
通过这种方式,您甚至可以同时向各个用户和群组发送消息。
这是你通常会遇到这类问题的方法吗?
答案 0 :(得分:3)
詹姆斯陈述......是正确的。
另外,请确保您不使用可引用多种主键的字段。 message_participants表中的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的方法。
答案 1 :(得分:2)
这是一个很好的问题。听起来你走在正确的轨道上。这将是我的方法:
表:
现在举个例子:假设用户向组发送消息,在message_groups中插入一行,并为该组的每个成员插入一行到message_users。这允许您捕获哪些组已发送消息以及当时哪些用户收到消息。可以在过去或将来从组中添加和删除用户,因此您必须记录发送邮件时组中的每个用户。只记录小组就无法逃脱。
获取用户的所有消息:
SELECT * FROM message INNER JOIN message_users ON message.id = message_users.message_id WHERE message_users.user_id = {user_id}
另外,请确保您不使用可引用多种主键的字段。 message_participants表中的mpid字段不应引用用户和组。
不确定为什么需要帖子。消息有多个帖子?希望这会有所帮助。