数据库建模:Facebook就像消息一样

时间:2010-11-26 08:43:43

标签: mysql database database-design

我试图模仿类似于FB的东西。基本上,用户可以在用户简档的各个部分(例如“墙”,“照片”等)发表评论。我认为以下模型可行:

===========================
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)

2 个答案:

答案 0 :(得分:3)

首先,对小点进行一些回应,让您保持关系数据库和数据库设计的直线和狭窄路径。

  1. 整个想法是将尽可能多的规则放在数据库中,放在一个地方,而不是放在代码中。几乎所有事情都可以通过DDL完成:FK约束; CHECK限制;和RULES(所有ISO / IEC / ANSI SQL要求)。然后,所有用户(您的应用程序都是用户)可以查看所有规则并更好地了解数据库。无论使用什么客户端执行代码,都可以保护数据库。 Db供应商(这意味着商业,而不是免费软件)实现这些约束比代码更可靠。

  2. 将行插入子表的要求(非约定)是父行必须首先存在。这就是FK约束的作用,它确保父行存在。在多对多表中,两个父行必须存在于子节点之前(具有两个FK,每个父节点一个)可以插入。

  3. types_id是一个可怕的想法,因为你破坏了设计规则,并删除了RI的可能性。最好有RI的单独列(每个父级的FK约束)。 (但还有更好的方法。)

  4. 您的所有Id列PK都应重命名为TableId。每个都应具有相同名称的Private DataType。列名称作为FK在任何存在的地方都保持不变。唯一的例外是你有两个FK到同一个父表:它应该是RoleTableId

  5. 解决此问题的最佳方法是什么?

    归一化。而且您将遇到需要解决的问题。因此再次标准化。并继续这样做,直到你没有问题要解决。

    1. 您的单个​​留言表已经到了一半。您已经直观地将两个表归一化为一个。但是有一些问题需要解决,所以让我们来处理它们。

      • 塞巴斯蒂安提供了两张多对多牌桌,所以我不再重复了
    2. 在您确定这是最终的(因此两个多对多表格是最终的)之前,我建议您标准化WallMedia。对我来说,看起来有很多常见的专栏。如果你将其标准化,你将获得一个表。由于Person是为了邀请Messages而展示或提供的东西,而且类型可以是{ Photo | Album | Mailbox | Wall },我会将其称为PersonFurniture或{ {1}}。

      • 如果最终成为一个表,那么您将不需要两个多对多表,只需一个。
    3. 回复评论

      1. 绘制模型比键入长时间的讨论更容易,更快捷。我考虑过你的大部分问题。请检查此问题并询问有关您不理解的任何问题的具体问题。
      2. Link to Social Network Data Model(第3页)

        Link to IDEF1X Notation适用于那些不熟悉关系建模标准的人。

        • 选择自己的表名和列名
        • PersonObject可以设置为Message.Subject或忽略,如果不是电子邮件。
        • CHAR(0)wall_message相同是一个问题,我已将它们规范化为一个表
        • email_message还是wall_message还是email_message是“发送”的问题,对吧?您可以通过CHECK约束轻松禁止任何消息类型的任何功能(例如分组)。
        • 你没有回答上述(2)
        • 我认为消息分组与媒体分组不同:想想相册上有消息列表的时间。
        • 什么都不是问题,造型的整个想法是,纸张便宜;关系dbs的整个想法是尽可能地使用约束,检查和规则。如果有什么不对的地方,我们可以改变它。

        (你想要种族问题中的种族(3级)或2级吗?)

答案 1 :(得分:1)

您可以拥有表格信息,然后是n:m关系表,即

message_to_wall:
- messageID
- wallID

message_to_media:
- messageID
- mediaID

这样,您可以保持参照完整性,并且只有一个消息表。

当然,这在技术上允许它将消息发布到墙上和媒体项目(照片等)。所以你不能轻易地限制它。

否则 - 如果你真的不需要关系数据库,你可以考虑使用像CouchDB或MongoDB这样的NoSQL数据库。您可以将所有这些评论直接存储在墙上或媒体文档中。这样,您就没有所有必需的JOIN查询,并且评论都链接到媒体或墙。