2010-11-26 65 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