Supongamos que tenemos esta sencilla tabla en la que almacenamos títulos de libros, junto con una puntuación (que vendría a ser la suma de votos que da un usuario que accede al sitio)
id | title | points |
---|---|---|
1 | Alicia en el País de las Maravillas | 358 |
2 | El Color de la Magia | 324 |
3 | Hamlet | 321 |
En principio suele abordarse este tipo de acciones con dos tareas:
- Comprobar si existe el elemento
- Ejecutar acción en base de datos en función de lo anterior
Es decir, la implementación exigiría realizar dos consultas consecutiva.El código para ilustrar como sería esta implementación (usando PHP y el framework de Joomla en este caso) podría ser:
$db=new JFactory::getDBO(); //comprobamos si existe el item $sql1='SELECT id,title,points FROM books WHERE title = "$titulo"'; $db->setQuery($sql1); $resultado=$db->loadObjectList(); //INSERT o UPDATE en función del resultado anterior if (empty($resultado)) {//libro no registrado; lo guardamos $sql2='INSERT INTO books (title,points) VALUES ("$titulo)","1");'; } else {//el libro está; incrementamos su puntuación $sql2='UPDATE books SET points=points+1'; } $db->setQuery($sql2); $db->query();
Tenemos que recurrir en este caso a PHP, como podría haber sido a otro lenguaje, para tomar una decisión de que consulta enviar al servidor de base de datos.
En este caso tenemos en mente MySQL.
Podremos resolver esto de otra forma más eficiente usando exclusivamente consultas, ahorrando así en líneas de código, consiguiendo una acción más portable a otros lenguajes y sobretodo ahorrando en tiempo de ejecución.
Hemos planteado el ejemplo con una única inserción, pero en el caso de tener que ejecutar miles de acciones de este tipo la diferencia de tiempo puede ser drástica (más si tenemos en cuenta el problema de tiempo de ejución máxima que tiene un script php en el servidor).
En primer lugar, puede que necesitemos permisos para modificar la estructura de la tabla con la que estamos trabajando, ya que necesitamos especificar que el título del libro va a ser un valor único, es decir, no permitimos el registro de varios libros con el mismo título.
Para ello ejecutamos la siguiente consulta (si es que el diseñador de la base de datos no lo ha tenido en cuenta...)
ALTER TABLE `books`
ADD UNIQUE (`title`);
Tras esto podremos realizar operaciones de inserción o actualización automática en el caso de que el item esté, usando una única consulta con ON DUPLICATE KEY:
INSERT INTO `books` (`title`, `points`)
VALUES ('el color de la magia','1')
ON DUPLICATE KEY
UPDATE `points`=`points`+1
Como dato a tener en cuenta (al menos según el cotejamiento de la BD) en el caso del ejemplo si otro usuario pretende insertar 'EL COLOR DE LA MAGIA' se activará ON DUPLICATE KEY, incrementándose el valor points en lugar de insertarse otro nuevo registro.
No se toman en cuenta las mayúsculas y minúsculas, lo cual en este caso no nos viene del todo mal, pero sí que podría ser necesario diferenciar en otros.
De cualquier forma, normalizar previamente el dato a tratar con la base de datos nos ayudará a tener un mayor control en este aspecto.
No hay comentarios:
Publicar un comentario