views:

111

answers:

2

Hi,

I am making a db schema for facebook like wall structure. I need to save wall posts, share a link, share a video stuff into my database. Till now I am able to make this schema :

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

Next I have to add the schema for adding the "share a link" and "share a video" feature.

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

Now with this schema:

1st case: When the wall post is inserted the [SharedLink], [SharedLinkTitle],[SharedLinkDesc], [SharedLinkImageSrc] columns will be inserted as null and rest of the columns will have the values.

2nd case: When the "link shared" is inserted the "[WallText]" column will be inserted as null and rest of the columns will have the values.

For my case 70% of the time the wall post will be made and 30 % "links" will be shared which means 70 % of the cases [SharedLink], [SharedLinkTitle],[SharedLinkDesc], [SharedLinkImageSrc] will be inserted as null. Now my concern is that is it okay to keep the null columns inserted or I should go for a separate table for "shared a link" purpose and have the separated table like this:

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 

I have to go in similar manner to add the schema for sharing the videos further. Please guide me in which direction should I move ?

+3  A: 

Because these are separate and distinct items (wall post/shared link/shared video), each with their own unique attributes, I'd recommend creating a separate table for each.

Joe Stefanelli
+1  A: 

Using two separate tables looks like a sensible approach here - the two tables seem to have very little in common. Combining unrelated objects into a single table and using NULLs for the columns that don't apply is typically a bad design.

More generally though, if you have two types objects that are different in some respects but also share some common features then another alternative you could look into is a technique that is sometimes called "table inheritance":

In your first approach you use one table that contains all the data. In your second approach you use two tables that are completely separate. The inheritance approach uses three tables - one for the common columns, and an extra table for each specialized type. You then use a foreign key relationship to relate the record in the common table to a record in one of the specific tables so that you can join to get the complete object. There are a few different ways to create this relationship that are described in the article I linked to above.

But don't overuse table inheritence. Two tables may happen to share a couple of columns for example (ID, insertion_date) but be otherwise two conceptually different things. Then it probably would not be appropriate to use this technique to factor out the common columns. I don't know enough about your specific situation to say whether it makes sense to use this technique on 'Wall posts' and 'Share a Link' posts, but you might want to consider it.

To give an example of when it could be useful to use this technique rather than having two separate tables: If you want to query for a user's ten most recent posts (regardless of whether they are wall posts or shared links) then it is useful to have a single table where you can get the IDs for these posts with a single simple query. If you have two completely separate tables with no relationship between them the query is more complex - you must first get the top 10 from each table, union the results, then get the top 10 from the union.

Mark Byers