Procedure de estadísticas que haga un INSERT o un UPDATE (I)

MySQL_Stored_Procedure_ProgrammingLa típica tabla de estadísticas, tiene una serie de registros, donde se almacenan valores que se van incrementando: visitas, votos, puntos, … Para la operación de incrementar las estadísticas, tenemos que contemplar dos casos:

  • Si no existen estadísticas sobre este registro, se tiene que crear el registro en la tabla de estadísticas con un INSERT
  • Si ya existen estadísticas, se tiene que incremenetar el valor del registro de la tabla de estadísticas con un UPDATE

Hay tres opciones a la hora de programar el sistema que incremente las estadísticas en MySQL:

  • Se hace una consulta a la Base de Datos con un SELECT, para saber si ya existe el registro o no en la tabla de estadísticas. Si no existe, hacemos otra petición a la Base de Datos haciendo un INSERT, y si existe, la petición será un UPDATE. En resumen, dos peticiones a la Base de Datos, con una operación cada una.
  • Se puede programar una STORED PROCEDURE que reciba el registro de las estadísticas. La Procedure se encarga de comprobar que exista el registro o no con un SELECT, y dependiendo del caso, hará la operación pertinente. En resumen, una petición a la Base de Datos, que al final ejecutará dos operaciones.
CREATE PROCEDURE `increment_stadistics`( IN uid int  )
BEGIN
DECLARE is_uid INT;
SELECT id INTO is_uid FROM stadistics WHERE id = uid LIMIT 1;
IF is_uid IS NULL THEN
INSERT INTO stadistics  (id, stats) values (uid, 1);
ELSE
UPDATE stadistics  SET stats = stats+1 WHERE id = uid LIMIT 1;
END IF;
END
  • Igual que el anterior, pero directamente hacer el INSERT … ON DUPLICATE KEY UPDATE, y que él mismo detecte a traves de un índice UNIQUE que ya existe el registro, y entonces lo incremente. En resumen, una petición a la Base de Datos, y una operación, pero es necesario un índice UNIQUE que puede ser la PRIMARY KEY de la tabla si nos sirve.
CREATE PROCEDURE increment_stadistics ( IN uid int )
BEGIN
DECLARE is_uid INT;
INSERT INTO stadistics (id, stats) VALUES (uid, 1)
ON DUPLICATE KEY UPDATE stats = stats +1;
END

El inconveniente de los índices, es que cuando se modifica la tabla (INSERT, UPDATE o DELETE), se han de regenerar. El caso de índice UNIQUE, implica además que antes de hacer un INSERT, tendrá que comprobar que no se dupliquen los registros. Como va a tener que comprobarlo, si no lo encuentra, hace el INSERT, y si lo encuentra, hace el UPDATE automáticamente.

En la siguiente entrada, veremos como modificar la procedure para que haga el incremento de una serie de registros con una sola llamada a la procedure.

6 comentarios en “Procedure de estadísticas que haga un INSERT o un UPDATE (I)

  1. Buen post, solo queria preguntar algo. ¿En vez de un procedimiento no es mejor crear un disparador (trigger) que se encargue de estas estadísticas?.
    Corregidme si me equivoco ya que estoy programando un sistema y puse un trigger que se ejecuta de forma similar que tu procedure.

    Saludos

  2. @Daniel Si, lo podrías hacer con un trigger, si el evento que dispara el trigger es producido por la base de datos. Pero si el evento es externo, como algo que dependa del servidor web o una petición especial, no podrás hacerlo con un trigger. Tendrás que hacer una procedure que será llamara cuando se produzca el evento a contabilizar.

  3. Hola @Daniel. Ojala me puedas ayudar, apenas comienzo con MySql y Java, tengo que hacer un programa que me separe los nombres (Nombre1, Nombre2, Apelli1, Apelli2) y me lo deje asi: (Nombres, Apelli1, Apelli2) para esto hice unn SP que me actualice los campos y me quedo asi:
    DROP PROCEDURE IF EXISTS Actualiza;

    DELIMITER//
    CREATE PROCEDURE Actualiza
    (
    IN sp_papellido CHAR(15),
    IN sp_sapellido CHAR(12),
    IN sp_nombres CHAR(25)
    )
    BEGIN
    UPDATE cargar_1_encrypt
    SET
    papellidos = sp_papellidos ,
    sapellidos = sp_sapellidos ,
    nombres = sp_nombres
    END
    DELIMITER ;//
    pero me arroja error si me puedes decir que estoy haciendo mal te agradeceria.
    Estare atento a tu respuesta.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *

Puedes usar las siguientes etiquetas y atributos HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>