我试图模仿类似于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)
答案 0 :(得分:3)
首先,对小点进行一些回应,让您保持关系数据库和数据库设计的直线和狭窄路径。
整个想法是将尽可能多的规则放在数据库中,放在一个地方,而不是放在代码中。几乎所有事情都可以通过DDL完成:FK约束; CHECK
限制;和RULES
(所有ISO / IEC / ANSI SQL要求)。然后,所有用户(您的应用程序都是用户)可以查看所有规则并更好地了解数据库。无论使用什么客户端执行代码,都可以保护数据库。 Db供应商(这意味着商业,而不是免费软件)实现这些约束比代码更可靠。
将行插入子表的要求(非约定)是父行必须首先存在。这就是FK约束的作用,它确保父行存在。在多对多表中,两个父行必须存在于子节点之前(具有两个FK,每个父节点一个)可以插入。
types_id
是一个可怕的想法,因为你破坏了设计规则,并删除了RI的可能性。最好有RI的单独列(每个父级的FK约束)。 (但还有更好的方法。)
您的所有Id
列PK都应重命名为TableId
。每个都应具有相同名称的Private DataType。列名称作为FK在任何存在的地方都保持不变。唯一的例外是你有两个FK到同一个父表:它应该是RoleTableId
。
解决此问题的最佳方法是什么?
归一化。而且您将遇到需要解决的问题。因此再次标准化。并继续这样做,直到你没有问题要解决。
您的单个留言表已经到了一半。您已经直观地将两个表归一化为一个。但是有一些问题需要解决,所以让我们来处理它们。
在您确定这是最终的(因此两个多对多表格是最终的)之前,我建议您标准化Wall
和Media
。对我来说,看起来有很多常见的专栏。如果你将其标准化,你将获得一个表。由于Person
是为了邀请Messages
而展示或提供的东西,而且类型可以是{ Photo | Album | Mailbox | Wall }
,我会将其称为PersonFurniture
或{ {1}}。
回复评论
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约束轻松禁止任何消息类型的任何功能(例如分组)。(你想要种族问题中的种族(3级)或2级吗?)
答案 1 :(得分:1)
您可以拥有表格信息,然后是n:m关系表,即
message_to_wall:
- messageID
- wallID
message_to_media:
- messageID
- mediaID
这样,您可以保持参照完整性,并且只有一个消息表。
当然,这在技术上允许它将消息发布到墙上和媒体项目(照片等)。所以你不能轻易地限制它。
否则 - 如果你真的不需要关系数据库,你可以考虑使用像CouchDB或MongoDB这样的NoSQL数据库。您可以将所有这些评论直接存储在墙上或媒体文档中。这样,您就没有所有必需的JOIN查询,并且评论都链接到媒体或墙。