2010-11-26 61 views
7

我試圖模仿類似於FB的東西。基本上,用戶可以在用戶簡檔的各個部分(例如「牆」,「照片」等)發佈評論。我想下面的模型將工作:數據庫建模:Facebook的消息

=========================== 
wall_message 
=========================== 
- id (PK) 
- parent_id (FK) 
- wall_owner_profile_id (FK, identify whose wall the message is for) 
- poster_profile_id (FK) 
- message 
- timestamp 

=========================== 
media_message 
=========================== 
- id (PK) 
- parent_id (FK) 
- media_id (FK, identify which photo, video, etc.) 
- poster_profile_id (FK) 
- message 
- timestamp 

parent_id允許將消息「組合」成一個相關的討論。第一條消息的parent_id將爲0,隨後的消息將具有PK作爲parent_id值(創建父 - 子關係)。

poster_profile_id標識誰發佈了該消息。

以上兩張表格非常相似。難道是一個好主意,把它們結合在一起,如:

=========================== 
message 
=========================== 
- id (PK) 
- parent_id (FK) 
- type (ENUM: "wall", "media", etc.) 
- types_id (FK, see explanation below) 
- poster_profile_id (FK) 
- message 
- timestamp 

在這種情況下,如果說,type是「牆」,然後types_id等於第一個表中的「wall_owner_profile_id」。例如,如果type是「媒體」,則types_id等於第二個表的media_id

我有點擔心,第二種方法需要一列來解釋另一列的含義。我認爲這個缺點是types_id不會有參照完整性(與「wall_owner_profile_id」和「media_id」不同)。

解決此問題的最佳方法是什麼?

編輯1:

看起來這是解決方案迄今:

=========================== 
message 
=========================== 
- message_id (PK) 
- parent_message_id (FK) 
- profile_id (FK, referring to who posted the message) 
- message 
- subject (applicable only for emails) 
- timestamp 

=========================== 
wall_message 
=========================== 
- message_id (FK) 
- profile_id (FK, referring to who received the message/owner of wall) 

=========================== 
media_message 
=========================== 
- message_id (FK) 
- media_id (FK) 

=========================== 
email_message 
=========================== 
- message_id (FK) 
- profile_id (FK, referring to who received the message) 
+1

你檢查新的數據模型? – PerformanceDBA 2010-11-29 13:43:20

回答

3

首先,回答一些小問題,讓你保持關係數據庫和db設計的直線和狹窄路徑。

  1. 整個想法是將盡可能多的規則就在數據庫中,在一個地方,而不是代碼。幾乎所有事情都可以通過DDL完成:FK約束; CHECK限制;和RULES(所有ISO/IEC/ANSI SQL要求)。然後,所有用戶(您的應用程序是用戶)都可以看到所有規則並更好地理解數據庫。這可以保護數據庫,不管用什麼客戶端來執行代碼。 Db供應商(這意味着商業,而不是免費軟件)實現這些約束比代碼更可靠。

  2. 要求(不是規則),用於插入行到一個子表是父行必須存在第一。這就是FK約束所做的,它確保父行存在。在一個多對多的表中,兩個父行必須存在才能插入子元素(帶有兩個FK,每個父元素一個)。

  3. types_id是一個可怕的想法,因爲你打破了設計規則,並刪除了RI的可能性。最好有獨立的列與RI(每個父母的FK約束)。 (但還有更好的辦法。)

  4. 所有Id列的PK,應該改名爲TableId。每個應具有相同名稱的私有數據類型。列名無論在哪裏存在,都可以用作FK。唯一的例外是你有兩個FK到同一個父表:它應該是RoleTableId

什麼是解決此問題的最佳方法?

標準化。而且您將遇到需要解決的暴露問題。因此再次標準化。並繼續這樣做,直到你沒有問題要解決。

  1. 您的單個消息表已經在這裏的一半。你直觀地將兩個表格歸一化。但有些問題需要解決,所以讓我們來處理它們。

    • 塞巴斯蒂安提供了兩個多對多的表格,所以我不再重複。
  2. 之前你決定,這是最後的(因此兩個多到很多表都是決賽),我建議你歸WallMedia。對我來說,它看起來像有許多共同的專欄。如果你規範化,你會得到一個表。既然是邀請Messages的目的暴露或提供由Person的事情,類型可以是{ Photo | Album | Mailbox | Wall },我把它叫做PersonFurniturePersonObject

    • 如果結果是一張表,那麼你不需要兩個多對多的表,只有一個。

迴應評論

  1. 更容易和更快地繪製模型,而不是鍵入長時間的討論。我想過你的大部分問題。請檢查此問題,並針對您不明白的任何問題提出具體問題。

Link to Social Network Data Model(第3頁)

Link to IDEF1X Notation對於那些誰不熟悉關係建模標準。

  • 選擇自己的表和列名
  • Message.Subject可以設置爲CHAR(0)或忽略,如果不是電子郵件。
  • wall_messageemail_message是相同的是一個問題,我已經正規化的他們到一個表
  • 無論是wall_messageemail_messagemedia_message是它是「送」裏的事,對不對?您可以通過CHECK約束輕鬆地禁止任何函數(例如分組)。
  • 你還沒有回答(2)以上
  • 我認爲消息分組與媒體分組有所不同:想一想當一個相冊上有一個消息列表。
  • 沒什麼問題,造型的整體思路是,紙張便宜;關係型數據庫的整體思想是儘可能地使用約束,檢查和規則。如果有什麼不對,我們可以改變它。

(你希望賽(3級)或2級在你的種族問題?)

1

你可以有你的表的消息,然後N:M關係表,即

message_to_wall: 
- messageID 
- wallID 

message_to_media: 
- messageID 
- mediaID 

這樣你保持參照完整性並且只有一個消息表。

這當然會在技術上允許它將消息發佈到牆上和媒體項目(照片等)。所以你不能輕易限制這一點。否則 - 如果您確實不需要關係數據庫,則可以考慮使用NoSQL數據庫,如CouchDB或MongoDB。您可以將所有這些評論存儲在牆上或媒體文檔中。這樣你就沒有所有需要的JOIN查詢,並且評論都鏈接到媒體或牆上。

+0

@Sebastian:我在使用MySQL。由於這兩個表可能具有相同的`messageId`,您是否發現設計中存在任何潛在的問題?我很確定我可以通過代碼防止這種情況發生,但是我很好奇從數據庫的角度來看是否存在問題? – StackOverflowNewbie 2010-11-26 09:01:57

+0

...以及我如何使用相同的基本設計來支持用戶之間的電子郵件消息? – StackOverflowNewbie 2010-11-26 09:31:04