Sistema de Puntuación y Opiniones Cinco Estrellas con MySQL

Lo que vamos a ver en este post es una manera de modelar en MySQL un sistema de puntuación y opiniones cinco estrellas, es decir, puntuaciones entre 1 – 5.

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.

Opiniones en Google Play para Angry BirdsLo 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:

  1. El sistema recogerá la votación del usuario para la imagen visualizada, junto con sus comentarios.
  2. Se almacenará la puntuación para la imagen mostrada y el usuario autenticado en la tabla image_vote.
  3. 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.
  4. 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).

Cuándo Adquirir una Licencia Comercial de MySQL

MySQL tiene licencia dual. ¿Qué quiere decir esto? Por una parte es libre, y por otra es comercial. Puedes obtener el software de MySQL bajo licencia GPL (v.2) o puedes comprar una licencia. Está muy extendida la sensación de que si ganas dinero con MySQL hay que comprar una licencia comercial.

A raíz de la publicación del post sobre la instalación de un servidor LAMP en Ubuntu, apareció un comentario en el mismo en el que el autor me solicitaba información acerca de si es obligatorio comprar una licencia comercial de MySQL al instalar en un cliente el sistema Ubuntu junto con este servidor.

MySQL tiene licencia dual. ¿Qué quiere decir esto? Por una parte es libre, y por otra es comercial. Puedes obtener el software de MySQL bajo licencia GPL (v.2) o puedes comprar una licencia. Está muy extendida la sensación de que si ganas dinero con MySQL hay que comprar una licencia comercial. Esto no es correcto del todo.

MySQL se distribuye bajo la licencia GPL, no es una licencia fácil de entender, por esto mismo MySQL confunde a muchos desarrolladores. ¿Hay que pagar para poder vender un producto que funciona con MySQL? Únicamente se requiere una licencia comercial en estos dos escenarios:

  1. Si queremos modificar el código de MySQL y queremos redistribuir estas modificaciones cobrando por ellas.
  2. Si queremos incluir MySQL dentro de nuestro software como uno solo. Hay que tener en cuenta que no significa que no podamos conectarnos con MySQL, si no que no podemos incluirlo en nuestro software. Por ejemplo, WordPress trabaja con PHP y se conecta a MySQL, pero no lo distribuye.

Muy importante. Si quieres incluir MySQL dentro de tu software y distribuirlo conjuntamente y no deseas comprar una licencia comercial, puedes hacerlo, pero tu software deberá estar licenciado de la misma forma, acogiéndote a la licencia GPL y liberar el código.

O sea, para cualquier otra cosa, no necesitamos una licencia comercial. Las siguientes cosas están permitidas bajo la licencia GPL:

  • Gestionar un negocio que te reporte beneficios usando MySQL
  • Modificar su código fuente como se desee.
  • Vender y distribuir MySQL (hay que hacerlo bajo licencia GPL también).
  • Redistribuir las modificaciones realizadas.

Otros puntos importantes que la licencia no obliga:

  • No requiere redistribuir las modificaciones realizadas a MySQL
  • No requiere de una licencia GPL del software que se conecta a MySQL
  • No obliga a que todo el software en su empresa también sea GPL

Para aclarar las ideas acerca de la licencia GPL, puedes consultar las FAQ de la licencia. Cómo observaréis todo software libre puede no ser gratis, dependiendo de la licencia bajo la que se acoja. El motor de base de datos PostgreSQL, por ejemplo, es otra alternativa para entornos de producción que se distribuye bajo su propia licencia, muy similar a la licencia MIT y mucho menos restrictiva que la GPL.

Instalar un servidor LAMP en Ubuntu (y II)

En el anterior post vimos cómo instalar todos los módulos del servidor LAMP, así como la configuración y puesta en marcha del servidor Apache. En éste veremos cómo activar el módulo PHP y la configuración de la BBDD MySQL.

En el anterior post vimos cómo instalar todos los módulos del servidor LAMP, así como la configuración y puesta en marcha del servidor Apache. En éste veremos cómo activar el módulo PHP y la configuración de la BBDD MySQL.

PHP

Para habilitar el módulo PHP teclearemos:

sudo a2enmod php5

En Linux nos pedirá introducir la contraseña de administrador. Una vez introducida se activará el módulo, y para que los cambios tengan efecto, debemos reiniciar Apache tecleando lo siguiente en línea de comandos:

sudo service apache2 restart

Al habilitar el módulo, internamente esto crea un enlace simbólico /etc/apache2/mods-enabled/php5 apuntando a /etc/apache2/mods-availble/php5.

Para comprobar la correcta instalación del módulo podemos hacer lo siguiente: En el directorio que habíamos habilitado como directorio de publicación (por defecto es /var/www y en la primera parte del artículo lo modificamos para que fuera /home/user/public_html el Document Root) creamos un fichero que llamaremos test.php con permisos de lectura, con esta única línea de código:

<?php phpinfo();?>

En un navegador tecleamos http://localhost/test.php en la barra de direcciones. Si puedes ver una descripción de la configuración de PHP5, el módulo está instalado correctamente.

MySQL

En el caso de que vayamos a acceder a la base de datos desde otros ordenadores de la red debemos especificar su dirección IP asociada. Debes observar que esto plantea un problema de seguridad, pues podrá ser accedida desde cualquier ordenador. Por lo tanto, si no necesitas acceder fuera de tu entorno local, pasa al paso siguiente.

Teclea:

nano /etc/mysql/my.cnf

y cambia la línea:

bind-address           = localhost

por la línea en la que especificas tu dirección IP (si es dinámica puedes comentar la línea):

bind-address           = 192.168.1.20

 

En el proceso de instalación se nos pidió una contraseña para el usuario ROOT de mySQL. Si no lo hicimos podemos hacerlo tecleando:

mysql -u root

y en la consola de mySQL tecleamos:

mysql> SET PASSWORD FOR 'root'@'localhost'
       = PASSWORD('yourpassword');

Debes tener en cuenta que todos los comandos mySQL pueden ocupar varias líneas en consola pero siempre deben acabar con punto y coma. Terminado este proceso o si ya habíamos especificado una contraseña podemos conectar de la manera:

mysql -u root -p

Si olvidaste la contraseña del usuario ROOT visita el siguiente enlace para recuperarla. Resetear contraseña ROOT mySQL.

Crear una base de datos

mysql> CREATE DATABASE database1;

Para comenzar a trabajar con la base de datos creada tecleamos:

mysql> USE database1;

A partir de aquí podemos crear tablas, insertar registros, etc. sobre la base de datos elegida.

Crear un usuario de mySQL

Para crear un usuario con todos los privilegios:

mysql> GRANT ALL PRIVILEGES ON *.* TO 'yourusername'@'localhost'
IDENTIFIED BY 'yourpassword' WITH GRANT OPTION;

Y para crear un usuario con privilegios limitados que sólo pueda acceder a la base de datos creada (por ejemplo database1):

mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX,
ALTER, CREATE TEMPORARY TABLES, LOCK TABLES ON database1.*
TO 'yourusername'@'localhost' IDENTIFIED BY 'yourpassword';

Para salir de la línea de comandos mySQL teclea:

mysql> \q

Todas estas tareas puedes realizarlas con una herramienta visual como MySQL Workbench para database architects, desarrolladores, y DBAs.

MySQL Workbench screenshot

MySQL Workbench provee herramientas para diseñar el modelo de datos, desarrollo SQL, y herramientas de administración más amigables para la configuración del servidor, administrador de usuarios y mucho más. MySQL Workbench está disponible para Windows, Linux y Mac OS. Puedes descargarlo aquí.

Instalar un servidor LAMP (Linux-Apache-MySQL-PHP) en Ubuntu (I)

Para instalar y configurar un servidor web y ejecutar un sitio o aplicación web en local, tienes que instalar un servidor LAMP o WAMP, sobre todo si tu sitio web es dinámico y utilizas o vas a utilizar una Base de Datos. Si eres usuario de Linux debes instalar un servidor LAMP, que es el acrónimo de Linux-Apache-MySQL-PHP. Si eres usuario Windows instalarás un servidor WAMP. A continuación veremos como instalarlo y configurarlo en Linux.

Para instalar y configurar un servidor web y ejecutar un sitio o aplicación web en local, tienes que instalar un servidor LAMP o WAMP, sobre todo si tu sitio web es dinámico y utilizas o vas a utilizar una Base de Datos. Si eres usuario de Linux debes instalar un servidor LAMP, que es el acrónimo de Linux-Apache-MySQL-PHP. Si eres usuario Windows instalarás un servidor WAMP. A continuación veremos como instalarlo y configurarlo en Linux. En mi caso uso la distribución Ubuntu 11.10.

Primero instalamos tasksell y el servidor LAMP:

sudo apt-get install tasksel
sudo tasksel install lamp-server

Instalar Apache 2

Con los siguientes comandos arrancamos, paramos y reiniciamos el servidor Apache, respectivamente:

sudo /etc/init.d/apache2 start
sudo /etc/init.d/apache2 stop
sudo /etc/init.d/apache2 restart

Una vez arrancado podemos probar la instalación tecleando la URL http://localhost en un navegador. Si aparece el mensaje “It Works!” que es el contenido del fichero html /var/www/index.html, todo funciona correctamente.

Si obtenemos un error acerca de que no se puede obtener un nombre de dominio o algo relacionado con este tema, debemos crear un nuevo fichero con el nombre fqdn en la ruta /etc/apache2/conf.d/. En él debemos añadir “ServerName localhost“. Podemos editar el fichero con el siguiente comando:

sudo nano /etc/apache2/conf.d/fqdn

Virtual Hosts

En Apache2 existen los llamados sites, que son configuraciones de ficheros que Apache2 lee de forma separada. Están disponibles en /etc/apache2/sites-available. Por defecto únicamente existe un site llamado default que es el que visualizamos cuando tecleamos http://localhost o http://127.0.0.1. Puedes tener diferentes configuraciones disponibles de sites y activar sólo las que necesites.

Ahora vamos a crear un site nuevo y lo habilitaremos en Apache 2:

  1. Primero copiamos el website por defecto como punto de partida: sudo cp /etc/apache2/sites-available/default /etc/apache2/sites-available/mysite
  2. Editamos el nuevo fichero de configuración en un editor de texto. Por ejemplo: gksudo gedit /etc/apache2/sites-available/mysite
  3. Cambiamos en el mismo el Document Root para apuntar a la nueva ruta. Por ejemplo, /home/user/public_html/
  4. Cambiamos la directiva Directory para que apunte al nuevo directorio. <Directory /home/user/public_html/>
  5. Puedes establecer logs diferentes para cada site. Para ello, cambia las directivas ErrorLog y CustomLog. Si tienes varios sites, esto puede ser de bastante ayuda.
  6. Guarda el fichero.

Una vez que hemos seguido los pasos anteriores debemos desactivar el site antiguo y activar el nuevo. Ubuntu provee dos pequeñas utilidades para esto: a2ensite para activar, y a2dissite para desactivar.

sudo a2dissite default && sudo a2ensite mysite

Para finalizar, debemos reiniciar Apache.

sudo /etc/init.d/apache2 restart

Si no existiera el directorio /home/user/public_html/ obtendríamos un mensaje de aviso.

Para probar que todo funciona correctamente creamos un fichero en /home/user/public_html llamado index.html con el siguiente código y tecleamos la URL http://localhost en un navegador:

<html><body><b>Hola! Esto funciona correctamente!</b></body></html>

En un próximo post veremos como configurar el módulo PHP de la instalación y la Base de Datos mySQL.

ACTUALIZACIÓN: Si te interesó el artículo puedes leer la segunda parte del mismo: Instalar un servidor LAMP en Ubuntu (y II).