views:

50

answers:

2

I have a table of "posts" and I want to keep track of the ratings for each post. Normally, I would add a rating field with int values in that same table which references another "rating" table that holds actual rating data. Is there anything wrong with removing that rating field and calling the ratings directly from the rating table based on postID? Posts table will have no direct reference to the rating, but the rating table references the post ID. Which way is better/correct. tia

+1  A: 

I think you've just become enlightened about good database design. The second approach is the correct one, the rating table has a Foreign Key PostId that references back to the Posts table.

I'm not sure how the first approach actually works, do you have single ratings field in the Posts table that references mulitple rows in the rating table? Do your ratings have a reference which isn't unique? Either way that isn't good practice, read up on normalisation and you'll get the idea.

MrTelly
the confusion for me is that I see a "post" as the object that has a rating. when I map the data to domain object, the rating field would be the id of the rating name found in the rating table.
zsharp
This sounds like you have a set of possible rating values, for example good, average, poor. And you want to assign such an rating to each post. This is a many to many mapping and you will actually require three tables to represent that.
Daniel Brückner
Can you edit the question with an example
MrTelly
+2  A: 

You should include the rating field directly in your posts table. It is a question of normalization and you win nothing if you seperate that value because there is no functional dependency.

In some rare situations you might add such fields as seperate tables. For example if you have to add the rating value to an existing table and you are unable to add a new column for whatever reason.

Or may be you can gain some performance if the rows are very large and change very infrequent while the rating value changes very frequent.

But I would not say that your case falls into neither category; so just keep it in the posts table.


I am going to summarize some common situations.

Posts
========
PostId           Ratings
Text             ==========
RatingId  ====>  RatingId
                 RatingName

Use this if you have a set of possible rating values, such as 'Good', 'Average', and 'Poor' and all posts share this values. RatingValue would be a string identifed by an id.

If the rating value is a simple number, just include it in the posts table. That is probably your point. Why include a integer rating value and not a string with a rating name? The difference is as follows. The integer rating should be included because every value is a legal rating. This is not true for the string ratings. They should be moved to a seperate table, because only a limited set of strings represent legal ratings.

Posts
===========
PostId
Text
RatingValue

If you have multiple ratings per post the following is the way to go for a limited set of possible ratings.

Posts            PostRatings
========         ===========        Ratings
PostId    <====  PostId             ===========
Text             RatingId     ===>  RatingId 
                                    RatingName

If you have integer ratings you put them back into the post ratings table. You need to add an artifical primary key if you require one because there is no natural primary key.

                 PostRatings
Posts            ==============
========         [PostRatingId]
PostId    <====  PostId
Text             RatingValue

If you associate a rating with a user and allow only one rating for a given post per user you get a natural primary key again.

Posts            PostRatings
========         ===========        User
PostId    <====  PostId             ===========
Text             UserId       ===>  UserId 
                 RatingValue        Name
Daniel Brückner