Search code examples
phpmysqlsqldatabaserating-system

mySQL Database - Storing Multi-Criteria Ratings


I've been doing a lot of searching and reading about rating systems, but couldn't find a solution to what I'm trying to achieve...

I have a website where users, once logged in, can submit a product. Now I want other users to be able to rate those products according to 3 different criteria. I'm using php and mySQL databases to store all of the information which is working great, I'm just not sure how to incorporate the ratings now.

At the moment I have a PRODUCTS database, which holds various tables according to their category. Here's an example of a table:

TOASTERS
---
ID (auto-incrementing)
Brand
Set
Number
Name
Edition
Image (stores the location of the image the user uploads)

Any user can then rate that row of the table out of 10 for 3 criteria (Quality, Price, Aesthetic). The user average of each criteria is displayed on each product page but I would like to store each of the user's individual ratings so that I can show a short history of their ratings on their profile page. Or have a live feed of the latest user ratings on the homepage.

What I'm trying to do is quite a lot like awwwwards.com. (See bottom-right of page to see the livefeed I'm talking about)

Thanks in advance!


Solution

  • I think you should use single PRODUCTS table or at least create PRODUCTS table and emulate inheritance between it and category tables.

    Having a table for each category can give some advantages if each category has some specific properties, but it can lead to neccesity of writing separate code to work with each table. Alternatively you can use two tables to store all custom properties 'vertically': PROPERTIES(propertyID,PropertyName), PROPVALUES(productID,propertyID,PropertyValue).

    If you choose to have multiple tables and emulate inheritance, it can be achieved like this:

    PRODUCTS
    ---
    ID (auto-incrementing)
    Brand
    Set
    Number
    Name
    Edition
    Image
    VoteCount    <+
    SumQuality    +-updated by trigger
    SumPrice      |
    SumAesthetic <+
    
    TOASTERS
    ---
    productID (PK and FK to PRODUCTS)
    (toaster specific fields go here, if any)
    

    Than you will be able to create table VOTES, referencing table PRODUCTS

    VOTES
    ---
    productID (FK to PRODUCTS)
    userID (FK to USERS)
    Quality    
    Price     
    Aesthetic
    VoteDateTime
    

    If it is true that overall product rating is queried much more often than voting history, as an optimization you can add fields VoteCount, AvgQuality, AvgPrice, AvgAesthetic to PRODUCTS table, as srdjans already supposed. You can update this extra fields by trigger on table VOTES or manually in PHP code.