数据库建模:Facebook的消息
我试图模仿类似于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
是“media”,那么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)
首先,对小的几点做出回应,以使您保持关系数据库和db设计的直线和狭窄路径。
整个想法是将尽可能多的规则放在数据库中,放在一个地方,而不是放在代码中。 几乎所有事情都可以通过DDL完成:FK约束; CHECK
约束; 和RULES
(所有ISO / IEC / ANSI SQL要求)。 然后,所有用户(您的应用程序是用户)都可以看到所有规则并更好地理解数据库。 这可以保护数据库,不管用什么客户端来执行代码。 Db供应商(这意味着商业,而不是免费软件)实现这些约束比代码更可靠。
将行插入子表的要求(不是约定)是父行必须首先存在。 这就是FK约束所做的,它确保父行存在。 在一个多对多的表中,两个父行必须存在才能插入子元素(带有两个FK,每个父元素一个)。
types_id
是一个可怕的想法,因为你破坏了设计规则,并删除了RI的可能性。 最好有独立的列与RI(每个父母的FK约束)。 (但还有更好的办法。)
所有的Id
列,PK,都应该重命名为TableId
。 每个应具有相同名称的私有数据类型。 列名无论在哪里存在,都可以用作FK。 唯一的例外是你有两个FK到同一个父表中:它应该是RoleTableId
。
解决这个问题最好的办法是什么?
规范化。 而且您将遇到需要解决的暴露问题。 因此再次标准化。 并继续这样做,直到你没有问题要解决。
你的单个消息表已经到了一半。 你直观地将两个表格归一化。 但有些问题需要解决,所以让我们来处理它们。
。
在你决定这是最终的(因此两个多对多的表格是最终的)之前,我建议你使用Normalize Wall
and Media
。 对我来说,它看起来像有许多共同的专栏。 如果你规范化,你会得到一个表。 由于这是一个由Person
为了邀请Messages
而暴露或提供的事物,并且类型可以是{ Photo | Album | Mailbox | Wall }
{ Photo | Album | Mailbox | Wall }
{ Photo | Album | Mailbox | Wall }
,我将其称为PersonFurniture
或PersonObject
。
对评论的回应
链接到社交网络数据模型 (第3页)
链接到不熟悉关系建模标准的人员的IDEF1X符号 。
Message.Subject
可以设置为CHAR(0)
或忽略。 wall_message
和email_message
是相同的不是问题,我已经将它们归一化为一个表格 wall_message
还是email_message
或media_message
都是“发送”的地方,对吧? 您可以通过CHECK约束轻松地禁止任何函数(例如分组)。 (你想在种族问题中选择种族(3个关卡)还是2个关卡?)
你可以有你的表格消息,然后是n:m关系表,即
message_to_wall:
- messageID
- wallID
message_to_media:
- messageID
- mediaID
这样你保持参照完整性,只有一个消息表。
这当然会在技术上允许它将信息发布到墙上和媒体项目(照片等)。 所以你不能轻易限制这一点。
否则 - 如果你不需要关系数据库,你可以考虑使用像CouchDB或MongoDB这样的NoSQL数据库。 您可以将所有这些评论存储在墙上或媒体文档中。 这样你就没有所有需要的JOIN查询,并且评论都链接到媒体或墙上。
链接地址: http://www.djcxy.com/p/49093.html上一篇: Database Modeling: Facebook like messages
下一篇: Dynamically added form fields are removed in form.cleaned