views:

154

answers:

7

I'll use the jQuery plugin for presenting the user with a nice interface

The request is to display 5 stars, up to a total score of 10 (2 points per star).
By now I thought about using 7/10 as a format for that value, but what if at some point in the future I'll receive a request like

We would like to give users more choice, let's increase the total score to 20 (so that each star contributes with a maximum of 4 points)

I'll end up with a table with mixed values for the "star rating" column: some will be like 7/10 while others will be like 14/20.

Is it ok for you to have this difference in the database and deal with it in the logic layer to have it consistent? Or is preferred another way so that querying the table will not result in inconsistent results outside the application?
Maybe floating point values could help me, is it better to store that value as a number less than or equal to one? So in each of the two examples the resulting value stored in the database would be 0,7, as a number, not a varchar, which can be queried also outside the application.

What do you think?

A: 

I would use two columns: one to hold the rating and one to hold the maximum rating. Since that maximum could change in the future, I would maintain it in the row with the rest of the data. You could use short ints so the amount of space required, even for large row counts, would be very small.

Tom Cabanski
+7  A: 

There are three options:

  1. Store the value as a fraction (which is, honestly, what I'd likely go with since it's the lowest maintenance
  2. Store the value in two columns, one for the rating and one for the maximum
  3. Store the value as a single column with an assumed maximum, then update all values when that maximum changes.

The first option is the most portable, since the maximum value and the representation of the rating are entirely client-side (client-side as far as the database is concerned, not client-side as in it's done at the user's machine).

The second just seems arbitrarily complex, unless you wish to continue to display a 7/10 rating as a 7 with 10 stars rather than a 14 with 20 stars.

The third requires the least up-front work, but requires a massive database update when changes are made to the rating scale.

Just to reiterate, I recommend storing the value as a float or double in the database and applying whatever scale is appropriate on the client side..

Adam Robinson
+1 for the well explained answer, but I think I'll do as z-boss suggested. In my scenario it's the easiest thing to do and a possible conversion in the future will not take that much.
Alberto Zaccagni
A: 

Depending on how exact you'd like it to be, either (1) store the rating as a double in the range [0,1], or (2) store 2 values, the numerator and denominator - the "rating" and the "max rating."

Matt Ball
A: 

I would suggest storing your scores as simple integers - if the rating is 7/10, store '7' in the db. If you then need to change it to a 20 point scale, just run an update query to double all the existing numbers. You could use floats if you need more precision, but for most ratings systems, integers should be fine.

Ray
+5  A: 

I would store it as a simple integer measured out of 100. That way you have plenty of granularity in case you want to increase the accuracy of the ratings in the future. No need to change any existing stored values either.

Mark Heath
Why introduce an artificial scale (100) when you could just store the value as a `float`?
Adam Robinson
Users will usually say "It's a 7 out of 10" which is just a fancy way of saying "It's 70%". Storing the data as percentage is imho the logical solution as percentages never change.
dbemerlin
Why not use a nice, round number—like 256? :)
Jeffrey L Whitledge
+1, yes this is what percentages are invented for.
stereofrog
+6  A: 

KISS
Just store the number of points and have application logic to represent it in the stars in IU.
If requirements change in the future, you will adjust the logic and run a conversion script if needed. That's all.

z-boss
Kiss always tends to slip away from me when searching for a solution, thanks.
Alberto Zaccagni
I think this is the best option, just store it as a `tinyint` 1..5. If requirements change in the future, it's a five minute script to update all existing data to the new scale. And if the requirements *don't* change (which is probably more likely), then you've not wasted time implementing something for no benefit. Besides, if requirements change, it's unlikely that they'll change in the way you expect ;)
Dean Harding
@codeka: nice point
Alberto Zaccagni
Data should, when possible, express what it means. While this is (*very marginally*) easier than storing the value as a float, it's less expressive. A value of .5 is pretty clear that it means "5/10" or "10/20" or whatever the scale is, since the user can never explicitly enter ".5". A value of "5" is not as expressive, as it could mean 5/10 or 5/20 or 5/45, since "5" is a valid user rating. If dealing with floats were more difficult, I'd agree...but it isn't.
Adam Robinson
A: 

I like the float idea, but none of the options are significantly outstanding. I only suggest that, whatever mechanism you choose, make sure the column is named appropriately.

The float option should be something like star_rating_ratio. The simple integer should be star_points_out_of_ten. The hundred point scale could be star_rating_percent.

(I've seen column names in the past that said "percent", but the data was a simple ratio. This keeps me up at night!)

Jeffrey L Whitledge
I would suggest naming integer value simply `Points` and giving more details in the comment. Name like `star_points_out_of_ten` will become bad if system changes to, let's say, points out of 20 and not use stars in the UI.
z-boss
@z-boss - if the interpretation of a column changes, then it's name should have to change as well. "But then every place that uses the column will have to change too!" Yes. That's exactly the point. Breaking changes should break sooner rather than later.
Jeffrey L Whitledge