2009-09-09 45 views
2

我想爲屬於單個用戶或用戶組的消息設計一個消息收件箱表模式。針對具有不同類別類型的討論系統的最佳數據庫設計?

比方說,我們有這些表已經:

  • 用戶的UID表(PK)與GID(PK)
  • 組表
  • 與GID(FK)groups_association表和uid(FK)

那麼,什麼將是消息和消息後表的最佳設計,以滿足這些要求:

  • 任何單個用戶可以消息的另一用戶
  • 任何單個用戶可以消息多個用戶
  • 任何單個用戶可以消息中的單個組的所有用戶(使用者的特定組中的數目可隨時間而改變)
  • 你應該能夠查詢屬於特定用戶的所有郵件

我現在的想法,就如同:

  1. 設置三個表:
    • 具有中級(PK)的消息,讓我們說的主題
    • message_participants與mpmid(FK),mptype ENUM( '用戶', '組')和MPID的(FK 型)
    • message_posts與msgmid(FK)參考消息表PK
  2. 要獲得的所有消息
    • 得到所有組爲特定用戶
    • 查詢message_participants WHERE(mptype = '用戶' AND MPID = UID)OR(mptype = '組' 和MPID IN(所有用戶組))

這種方式,你甚至可以將消息發送到個人用戶和羣體。

這是通常將如何處理這一類型的問題?

+0

爲什麼消息屬於用戶組?爲什麼不復制郵件並將其發送給組中的每個成員?你的要求是否說明消息必須屬於一個組?只是好奇。 – 2009-09-09 17:25:56

+0

好吧,如果我要向每個組成員發送單獨的消息,那麼如果該用戶回覆消息,則必須將其發送給組的所有成員,等等。因此,我在想,必須有一種更好的方式來存儲郵件的一個副本。 我相信你可以有另一臺連接個別職位有可能在該消息是否已讀或特定用戶刪除持有另一列用戶... – 2009-09-09 21:21:04

回答

2

這是一個很好的問題。聽起來像你在正確的軌道上。這裏是我的方法:

表:

  • 消息與ID,USER_ID,主題
  • message_users與ID(PK),MESSAGE_ID(FK),USER_ID(FK)
  • message_groups ID爲(PK),MESSAGE_ID(FK)

現在舉一個例子:假設一個用戶向一個組發送一條消息,在message_groups中插入一行,併爲該組的每個成員插入一行到message_users中。這使您可以捕獲哪些組發送了該消息,以及哪些用戶此時收到了該消息。用戶可以在過去或將來從組中添加和刪除,因此您必須在發送消息時記錄組中的每個用戶。只記錄這個組,你無法脫身。

要得到的所有消息的用戶:

SELECT * FROM消息 INNER JOIN message_users ON message.id = message_users.message_id WHERE message_users.user_id = {}的user_id

另外,還要確保你不要使用可以引用多種主鍵的字段。 message_participants表中的mpid字段不應引用用戶和組。

不知道爲什麼你需要帖子。消息是否有多個帖子?希望這可以幫助。

+0

感謝您的回答。你沒有爲多個主鍵使用列。在創建消息時插入每個用戶的方法是最初不想做的事情,但是當我更多地考慮它時,似乎最合理的做法是加入一個組的新用戶不需要看到在他們加入組之前創建的消息。 我提到了POSTS表,因爲每條消息都可以在初始消息上有「參與者」評論。我想我應該稱之爲某種「討論」...... – 2009-09-10 16:16:23

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的方法。

+0

謝謝亞歷克斯,你的方法也值得考慮。正如我在上面的評論中提到的那樣,我會堅持讓新用戶加入一個沒有看到舊信息的小組......同意術語不是很簡潔。 – 2009-09-10 16:20:07

相關問題