Facebook的DB Schema,如Wall +“共享链接”

时间:2010-09-16 19:40:00

标签: sql-server sql-server-2005 database-design schema database-schema

我正在为像facebook结构的facebook制作数据库架构。我需要保存墙贴,共享链接,将视频内容分享到我的数据库中。直到现在我能够制作这个架构:

GO
CREATE TABLE [Wall]
    (
      [ID] [int] NOT NULL IDENTITY(1, 1) ,
      [PostText] [nvarchar](MAX)
      [PostedByUserID] [int] NULL ,
      [PostedOnUserID] [int] NULL ,
      [DateCreated] [datetime] NULL 
    )
GO   

接下来,我必须添加用于添加“共享链接”和“共享视频”功能的架构。

GO
CREATE TABLE [Wall]
    (
      [ID] [int] NOT NULL IDENTITY(1, 1) ,
      [WallText] [nvarchar](MAX)
      [PostedByUserID] [int] NULL ,
      [PostedOnUserID] [int] NULL ,
      [DateCreated] [datetime] NULL,

      [SharedLink] [nvarchar](1024)  NULL ,
      [SharedLinkTitle] [nvarchar](512)  NULL ,
      [SharedLinkDesc] [nvarchar](512)  NULL ,
      [SharedLinkImageSrc] [nvarchar](512)  NULL 
    )
GO

现在使用此架构:

第一种情况:当插入墙贴时,[SharedLink],[SharedLinkTitle],[SharedLinkDesc],[SharedLinkImageSrc]列将插入为空,其余列将具有值。

第二种情况:当插入“链接共享”时,“[WallText]”列将被插入为空,其余列将具有值。

对于我的情况,70%的时间将发布墙贴,30%的“链接”将被共享,这意味着70%的案例[SharedLink],[SharedLinkTitle],[SharedLinkDesc],[SharedLinkImageSrc]将是插入为null。现在我担心的是,是否可以保持插入空列,或者我应该为“共享链接”目的找到一个单独的表,并使用这样的分隔表:

GO
CREATE TABLE [LinkShared]
    (
      [ID] [int] NOT NULL IDENTITY(1, 1) ,
      [PostedByUserID] [int] NULL ,
      [PostedOnUserID] [int] NULL ,
      [SharedLink] [nvarchar](1024)  NULL ,
      [SharedLinkTitle] [nvarchar](512)  NULL ,
      [SharedLinkDesc] [nvarchar](512)  NULL ,
      [SharedLinkImageSrc] [nvarchar](512)  NULL 
    )
GO 

我必须以类似的方式添加架构以进一步分享视频。请指导我应该朝哪个方向移动?

2 个答案:

答案 0 :(得分:6)

因为这些是独立且不同的项目(墙贴/共享链接/共享视频),每个项目都有自己独特的属性,我建议为每个项目创建一个单独的表格。

答案 1 :(得分:3)

使用两个单独的表看起来像是一种明智的方法 - 这两个表似乎没有什么共同之处。将不相关的对象组合到单个表中并对不适用的列使用NULL通常是一个糟糕的设计。

更一般地说,如果你有两种类型的对象在某些方面有所不同,但也有一些共同的特性,那么你可以研究的另一种选择是一种有时被称为“表继承”的技术:

在第一种方法中,您使用一个包含所有数据的表。在第二种方法中,您使用两个完全独立的表。继承方法使用三个表 - 一个用于公共列,另一个表用于每个专用类型。然后,使用外键关系将公用表中的记录与其中一个特定表中的记录相关联,以便您可以联接以获取完整对象。创建此关系有几种不同的方法,我在上面链接的文章中对此进行了描述。

但是不要过度使用表继承。例如,两个表可能碰巧共享几列(ID,insertion_date),但在两个概念上是不同的。那么使用这种技术来分解公共列可能是不合适的。我不太了解您的具体情况,说明在“帖子帖子”和“分享链接”帖子中使用这种技术是否合理,但您可能需要考虑它。

举一个例子说明何时使用这种技术而不是有两个单独的表是有用的:如果你想查询用户的十个最新帖子(无论它们是墙上帖还是共享链接)那么它有一个单独的表,您可以通过一个简单的查询获取这些帖子的ID。如果你有两个完全独立的表,它们之间没有关系,那么查询就更复杂了 - 你必须先从每个表中获得前10名,然后将结果合并,然后从联合中获得前10名。