Todos hemos visto, e incluso hemos votado o aportado alguna opinión en multitud de sitios sobre algún producto, alguna app, hotel o restaurante, o alguna canción/álbum de nuestro artista favorito. Es típico pulsar sobre 5 pequeñas estrellas para valorar en el rango 1 a 5 (1 = malo, 5 = excelente), de manera que la contabilización de las votaciones de todos los usuarios nos dará una puntuación media de lo que opina la gente.
Lo que vamos a ver en este post es una manera de modelar en base de datos un sistema de votaciones y opiniones, de manera que el código a escribir en la parte servidora (PHP, RoR, Java) sea el menor posible. Imaginemos un sistema en el que tenemos una colección de imágenes. Los usuarios autenticados que visitan la exposición virtual de dichas imágenes pueden valorar de 1 – 5 cada una de ellas. Opcionalmente pueden comentar algo sobre cada una, y para todas ellas se muestra la votación media así como el total de votos emitidos. Este ejemplo se ha desarrollado con MySQL.
En base de datos tendremos una tabla que llamaremos image para almacenar todas las imágenes, identificadas con un id único (image_id). Además almacenaremos su número de votos (num_votes), la puntuación total (total_score) y la puntuación media (rating), es decir, la puntuación total / número de votos:
drop table if exists image;
create table image
(
image_id int unsigned not null auto_increment primary key,
caption varchar(255) not null,
num_votes int unsigned not null default 0,
total_score int unsigned not null default 0,
rating decimal(8,2) not null default 0
)
engine = innodb;
Además, crearemos una tabla donde almacenaremos todas las votaciones y valoraciones de los usuarios. Para cada voto almacenaremos el id del usuario (user_id), el id de la imagen (image_id) y la puntuación personal de 1 a 5. Como opción podemos añadir una opinión (review) que explique su votación.
drop table if exists image_vote;
create table image_vote
(
image_id int unsigned not null,
user_id int unsigned not null,
score tinyint unsigned not null default 0,
review varchar(4000) null,
primary key (image_id, user_id)
)
engine = innodb;
Por último necesitamos que los campos num_votes, total_score y rating de la primera tabla (image) se actualicen cada vez que se reciba un voto y se almacene dentro de la tabla image_vote. Para ello generamos un trigger en BBDD que se ejecute tras una inserción en la tabla image_vote, aumentando en uno el número de votos, sumando la puntuación otorgada a la puntuación total, y finalmente recalculando la media.
create trigger image_vote_after_ins_trig after insert on image_vote
for each row
begin
update image set
num_votes = num_votes + 1,
total_score = total_score + new.score,
rating = total_score / num_votes
where
image_id = new.image_id;
end
Con este modelo que hemos creado en base de datos, el procedimiento funcionará de la siguiente manera:
- El sistema recogerá la votación del usuario para la imagen visualizada, junto con sus comentarios.
- Se almacenará la puntuación para la imagen mostrada y el usuario autenticado en la tabla image_vote.
- Automáticamente se actualizará el registro de la imagen seleccionada en la tabla image. El número de votos se incrementará en uno, la puntuación total se incrementará con la puntuación otorgada. Asimismo se calculará la nueva puntuación media.
- Al consultar la imagen de nuevo mostraremos la nueva puntuación media junto con el número total de votos.
Me gusta esta solución por su sencillez, minimizando el código que tenemos que escribir en la parte servidora, delegando toda la lógica en la capa de Base de Datos. Se puede completar mostrando las opiniones de los usuarios, junto con la puntuación que aportaron, e incluso el número de votos agrupados por los distintos valores (1 – 5).
8 respuestas a “Sistema de Puntuación y Opiniones Cinco Estrellas con MySQL”
Muchas felicidades, te luciste lo instalaremos a la brevedad. Felicidades por tu trabajo.
Gracias
Gracias Antonio, me alegro de que os sea de utilidad.
Gracias por leer mi blog.
Saludos
Muy bueno!!! Gracias por esta información me ha sido de mucha utilidad y me facilito mucho las cosas!!!
Gracias Leonardo, comentarios como el tuyo me animan a publicar soluciones que puedan ser de utilidad para todos.
Mil gracias por leerme. Saludos
Muchas Gracias !! Pronto lo estaré utilizando !!
Muchas gracias! justo lo que andaba buscando! se agradece el aporte!
Muy util tu articulo. Gracias
buenas tardes a mi no me funciono el disparador no entiendo por que y e intentado modificarlo gracias espero ayuda