One place for hosting & domains

      administrar

      Cómo usar ps, kill y nice para administrar procesos en Linux


      Introducción


      Un servidor Linux, como cualquier otro equipo con el que pueda estar familiarizado, ejecuta aplicaciones. Para el equipo, estos se consideran “procesos”.

      Mientras que Linux se encargará de la administración de bajo nivel, entre bastidores, en el ciclo de vida de un proceso, se necesitará una forma de interactuar con el sistema operativo para administrarlo desde un nivel superior.

      En esta guía, explicaremos algunos aspectos sencillos de la administración de procesos. Linux proporciona una amplia colección de herramientas para este propósito.

      Exploraremos estas ideas en un VPS de Ubuntu 12.04, pero cualquier distribución moderna de Linux funcionará de manera similar.

      Cómo ver los procesos en ejecución en Linux


      top


      La forma más sencilla de averiguar qué procesos se están ejecutando en su servidor es ejecutar el comando top:

      top***
      
      top - 15:14:40 up 46 min,  1 user,  load average: 0.00, 0.01, 0.05 Tasks:  56 total,   1 running,  55 sleeping,   0 stopped,   0 zombie Cpu(s):  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st Mem:   1019600k total,   316576k used,   703024k free,     7652k buffers Swap:        0k total,        0k used,        0k free,   258976k cached   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND               1 root      20   0 24188 2120 1300 S  0.0  0.2   0:00.56 init                   2 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kthreadd               3 root      20   0     0    0    0 S  0.0  0.0   0:00.07 ksoftirqd/0            6 root      RT   0     0    0    0 S  0.0  0.0   0:00.00 migration/0            7 root      RT   0     0    0    0 S  0.0  0.0   0:00.03 watchdog/0             8 root       0 -20     0    0    0 S  0.0  0.0   0:00.00 cpuset                 9 root       0 -20     0    0    0 S  0.0  0.0   0:00.00 khelper               10 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kdevtmpfs
      

      La parte superior de la información ofrece estadísticas del sistema, como la carga del sistema y el número total de tareas.

      Se puede ver fácilmente que hay 1 proceso en ejecución y 55 procesos en reposo (es decir, inactivos/que no usan los recursos de la CPU).

      La parte inferior tiene los procesos en ejecución y las estadísticas de uso.

      htop


      Una versión mejorada de top, llamada htop, está disponible en los repositorios. Instálelo con este comando:

      sudo apt-get install htop
      

      Si ejecutamos el comando htop, veremos que hay una pantalla más fácil de usar:

      htop***
      
        Mem[|||||||||||           49/995MB]     Load average: 0.00 0.03 0.05   CPU[                          0.0%]     Tasks: 21, 3 thr; 1 running   Swp[                         0/0MB]     Uptime: 00:58:11   PID USER      PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command  1259 root       20   0 25660  1880  1368 R  0.0  0.2  0:00.06 htop     1 root       20   0 24188  2120  1300 S  0.0  0.2  0:00.56 /sbin/init   311 root       20   0 17224   636   440 S  0.0  0.1  0:00.07 upstart-udev-brid   314 root       20   0 21592  1280   760 S  0.0  0.1  0:00.06 /sbin/udevd --dae   389 messagebu  20   0 23808   688   444 S  0.0  0.1  0:00.01 dbus-daemon --sys   407 syslog     20   0  243M  1404  1080 S  0.0  0.1  0:00.02 rsyslogd -c5   408 syslog     20   0  243M  1404  1080 S  0.0  0.1  0:00.00 rsyslogd -c5   409 syslog     20   0  243M  1404  1080 S  0.0  0.1  0:00.00 rsyslogd -c5   406 syslog     20   0  243M  1404  1080 S  0.0  0.1  0:00.04 rsyslogd -c5   553 root       20   0 15180   400   204 S  0.0  0.0  0:00.01 upstart-socket-br
      

      Puede aprender más sobre cómo usar top y htop aquí.

      Cómo usar ps para realizar una lista de procesos


      top y htop proporcionan una buena interfaz para ver los procesos en ejecución, similar a la de un administrador de tareas gráfico.

      Sin embargo, estas herramientas no siempre son lo suficientemente flexibles para cubrir adecuadamente todos los escenarios. Un poderoso comando llamado ps generalmente es la respuesta a estos problemas.

      Cuando se invoca sin argumentos, el resultado puede ser un poco escaso:

      ps***
      
        PID TTY          TIME CMD  1017 pts/0    00:00:00 bash  1262 pts/0    00:00:00 ps
      

      Este resultado muestra todos los procesos asociados con el usuario actual y la sesión de terminal. Eso tiene sentido porque, actualmente, solo estamos ejecutando bash y ps con este terminal.

      Para obtener un panorama más completo de los procesos en este sistema, podemos ejecutar lo siguiente:

      ps aux***
      
      USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND root         1  0.0  0.2  24188  2120 ?        Ss   14:28   0:00 /sbin/init root         2  0.0  0.0      0     0 ?        S    14:28   0:00 [kthreadd] root         3  0.0  0.0      0     0 ?        S    14:28   0:00 [ksoftirqd/0] root         6  0.0  0.0      0     0 ?        S    14:28   0:00 [migration/0] root         7  0.0  0.0      0     0 ?        S    14:28   0:00 [watchdog/0] root         8  0.0  0.0      0     0 ?        S<   14:28   0:00 [cpuset] root         9  0.0  0.0      0     0 ?        S<   14:28   0:00 [khelper] . . .
      

      Estas opciones ordenan a ps que muestre los procesos de propiedad de todos los usuarios (independientemente de su asociación con el terminal) en un formato fácil de usar.

      Para ver una vista de estructura jerárquica, en la que se ilustran las relaciones jerárquicas, podemos ejecutar el comando con las siguientes opciones:

      ps axjf***
      
       PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND     0     2     0     0 ?           -1 S        0   0:00 [kthreadd]     2     3     0     0 ?           -1 S        0   0:00  _ [ksoftirqd/0]     2     6     0     0 ?           -1 S        0   0:00  _ [migration/0]     2     7     0     0 ?           -1 S        0   0:00  _ [watchdog/0]     2     8     0     0 ?           -1 S<       0   0:00  _ [cpuset]     2     9     0     0 ?           -1 S<       0   0:00  _ [khelper]     2    10     0     0 ?           -1 S        0   0:00  _ [kdevtmpfs]     2    11     0     0 ?           -1 S<       0   0:00  _ [netns] . . .
      

      Como puede ver, el proceso kthreadd se muestra como proceso principal de kstadd/0 y los demás.

      Una nota sobre las ID de procesos


      En Linux y sistemas tipo Unix, a cada proceso se le asigna un ID de proceso o PID. Esta es la forma en que el sistema operativo identifica y realiza un seguimiento de los procesos.

      Una forma rápida de obtener el PID de un proceso es con el comando pgrep:

      pgrep bash***
      
      1017
      

      Esto simplemente consultará el ID del proceso y lo mostrará en el resultado.

      El primer proceso que se generó en el arranque, llamado init, recibe el PID “1”.

      pgrep init***
      
      1
      

      Entonces, este proceso es responsable de engendrar todos los demás procesos del sistema. Los procesos posteriores reciben números PID mayores.

      Un proceso principal es el proceso que se encargó de generarlo. Los procesos principales tienen un PPID, que puede ver en los encabezados de las columnas en muchas aplicaciones de administración de procesos, incluidos top, htop y ps.

      Cualquier comunicación entre el usuario y el sistema operativo sobre los procesos implica traducir entre los nombres de procesos y los PID en algún momento durante la operación. Este es el motivo por el que las utilidades le indican el PID.

      Las relaciones principal-secundario


      Para crear un proceso secundario se deben seguir dos pasos: fork(), que crea un nuevo espacio de direcciones y copia los recursos propiedad del principal mediante copy-on-write para que estén disponibles para el proceso secundario; y exec(), que carga un ejecutable en el espacio de direcciones y lo ejecuta.

      En caso de que un proceso secundario muera antes que su proceso principal, el proceso secundario se convierte en un zombi hasta que el principal haya recopilado información sobre él o haya indicado al núcleo que no necesita esa información. Luego, los recursos del proceso secundario se liberarán. Sin embargo, si el proceso principal muere antes que el secundario, init adoptará el secundario, aunque también puede reasignarse a otro proceso.

      Cómo enviar señales a los procesos en Linux


      Todos los procesos en Linux responden a señales. Las señales son una forma de decirle a los programas que terminen o modifiquen su comportamiento.

      Cómo enviar señales a los procesos por PID


      La forma más común de pasar señales a un programa es con el comando kill.

      Como es de esperar, la funcionalidad predeterminada de esta utilidad es intentar matar un proceso:

      kill PID_of_target_process

      Esto envía la señal TERM al proceso. La señal TERM indica al proceso debe terminar. Esto permite que el programa realice operaciones de limpieza y cierre sin problemas.

      Si el programa tiene un mal comportamiento y no se cierra cuando se le da la señal TERM, podemos escalar la señal pasando la señal KILL:

      kill -KILL PID_of_target_process

      Esta es una señal especial que no se envía al programa.

      En su lugar, se envía al núcleo del sistema operativo, que cierra el proceso. Eso se utiliza para eludir los programas que ignoran las señales que se les envían.

      Cada señal tiene un número asociado que puede pasar en vez del nombre. Por ejemplo, puede pasar “-15” en lugar de “-TERM” y “-9” en lugar de “-KILL”.

      Cómo usar señales para otros fines


      Las señales no solo se utilizan para cerrar programas. También pueden usarse para realizar otras acciones.

      Por ejemplo, muchos demonios se reinician cuando reciben la señal HUP o la señal de colgar. Apache es un programa que funciona así.

      sudo kill -HUP pid_of_apache

      El comando anterior hará que Apache vuelva a cargar su archivo de configuración y reanude sirviendo contenidos.

      Puede enumerar todas las señales que puede enviar con kill escribiendo lo siguiente:

      kill -l***
      
      1) SIGHUP    2) SIGINT   3) SIGQUIT  4) SIGILL   5) SIGTRAP  6) SIGABRT  7) SIGBUS   8) SIGFPE   9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM . . .
      

      Cómo enviar señales a los procesos por nombre


      Aunque la forma convencional de enviar señales es mediante el uso de PID, también hay métodos para hacerlo con nombres de procesos regulares.

      El comando pkill funciona casi exactamente igual que kill, pero funciona con un nombre de proceso en su lugar:

      pkill -9 ping
      

      El comando anterior es el equivalente a:

      kill -9 `pgrep ping`
      

      Si quiere enviar una señal a todas las instancias de un determinado proceso, puede utilizar el comando killall:

      killall firefox
      

      El comando anterior enviará la señal TERM a todas las instancias de firefox que se estén ejecutando en el equipo.

      Cómo ajustar las prioridades de los procesos


      A menudo, querrá ajustar qué procesos reciben prioridad en un entorno de servidor.

      Algunos procesos pueden considerarse como una misión crítica para su situación, mientras que otros pueden ejecutarse siempre que haya recursos sobrantes.

      Linux controla la prioridad a través de un valor llamado niceness.

      Las tareas de alta prioridad se consideran menos buenas porque no comparten los recursos tan bien. Por otro lado, los procesos de baja prioridad son buenos porque insisten en tomar solo los recursos mínimos.

      Cuando ejecutamos top al principio del artículo, había una columna marcada como “NI”. Este es el valor bueno del proceso:

      top***
      
      Tasks: 56 total, 1 running, 55 sleeping, 0 stopped, 0 zombie Cpu(s):  0.0%us,  0.3%sy,  0.0%ni, 99.7%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st Mem:   1019600k total,   324496k used,   695104k free,     8512k buffers Swap:        0k total,        0k used,        0k free,   264812k cached   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND            1635 root      20   0 17300 1200  920 R  0.3  0.1   0:00.01 top                    1 root      20   0 24188 2120 1300 S  0.0  0.2   0:00.56 init                   2 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kthreadd               3 root      20   0     0    0    0 S  0.0  0.0   0:00.11 ksoftirqd/0
      

      Los valores buenos pueden oscilar entre “-19/-20” (máxima prioridad) y “19/20” (mínima prioridad) dependiendo del sistema.

      Para ejecutar un programa con un determinado valor bueno, podemos usar el comando nice:

      nice -n 15 command_to_execute

      Esto solo funciona cuando se inicia un nuevo programa.

      Para alterar el valor bueno de un programa que ya se está ejecutando, usamos una herramienta llamada renice:

      renice 0 PID_to_prioritize

      Nota: Mientras que nice funciona necesariamente con un nombre de comando, renice funciona invocando al PID del proceso

      Conclusión


      La administración de procesos es un tema que a veces resulta difícil de entender para los nuevos usuarios, debido a que las herramientas utilizadas son diferentes a sus contrapartes gráficas.

      Sin embargo, las ideas son familiares e intuitivas, y, con un poco de práctica, se convertirá en algo natural. Dado que los procesos interviene en todo lo que se hace con un sistema informático, aprender a controlarlos de forma eficaz es una habilidad esencial.

      Por Justin Ellingwood



      Source link

      Cómo administrar conjuntos ordenados en Redis


      Introducción

      Redis es un almacén de datos clave-valor en memoria de código abierto. En Redis, los conjuntos ordenados son un tipo de datos similares a los conjuntos, ya que ambos son grupos de cadenas que no se repiten. La diferencia es que cada componente de un conjunto ordenado se asocia a una puntuación, lo que permite ordenarlos de la menor a la mayor. Como en el caso de los conjuntos, todos los componentes de un conjunto ordenado deben ser únicos, aunque varios pueden compartir la misma puntuación.

      En este tutorial, se explica la forma de crear conjuntos ordenados, obtener y eliminar sus componentes y crear nuevos conjuntos ordenados a partir de conjuntos existentes.

      Cómo usar esta guía

      Esta guía está escrita a modo de ayuda memoria con ejemplos independientes. Lo alentamos a ir directamente a cualquier sección que sea pertinente para la tarea que desee completar.

      Los comandos que se muestran en esta guía se probaron en un servidor de Ubuntu 18.04 con Redis 4.0.9. Para configurar un entorno similar, puede seguir el paso 1 de nuestra guía Cómo instalar y proteger Redis en Ubuntu 18.04. Mostraremos el comportamiento de estos comandos ejecutándolos con redis-cli, la interfaz de línea de comandos de Redis. Tenga en cuenta que si utiliza una interfaz de Redis diferente (por ejemplo, Redli), el resultado exacto de algunos comandos puede diferir.

      De forma alternativa, podría proporcionar una instancia de base de datos de Redis gestionada para probar estos comandos, pero tenga en cuenta que, dependiendo del nivel de control que permita su proveedor de base de datos, es posible que algunos comandos de esta guía no funcionen según lo descrito.  Para proporcionar una base de datos gestionada de DigitalOcean, consulte nuestra documentación sobre bases de datos gestionadas. Luego, debe instalar Redli o configurar un túnel TLS para establecer conexión con la base de datos gestionada mediante TLS.

      Crear conjuntos ordenados y añadir componentes

      Para crear un conjunto ordenado, utilice el comando zadd. zadd acepta como argumento el nombre de la clave que contendrá el conjunto ordenado, seguido de la puntuación del componente que añada y el valor del propio componente. Con el siguiente comando, se creará una clave de conjunto ordenado denominada faveGuitarists con un componente, "Joe Pass", que tiene una puntuación de 1:

      • zadd faveGuitarists 1 "Joe Pass"

      zadd mostrará un entero que indica la cantidad de componentes añadidos al conjunto ordenado si se creó de forma correcta.

      Output

      (integer) 1

      Puede añadir más de un componente a un conjunto ordenado con zadd. Tenga en cuenta que no es necesario que las puntuaciones sean secuenciales; puede haber brechas entre ellas, y varios componentes de un mismo conjunto ordenado pueden compartir la misma puntuación:

      • zadd faveGuitarists 4 "Stephen Malkmus" 2 "Rosetta Tharpe" 3 "Bola Sete" 3 "Doug Martsch" 8 "Elizabeth Cotten" 12 "Nancy Wilson" 4 "Memphis Minnie" 12 "Michael Houser"

      Output

      (integer) 8

      zadd puede aceptar las siguientes opciones, que debe ingresar después del nombre de clave y antes de la puntuación del primer componente:

      • NX o XX: estas opciones tienen efectos opuestos. Por lo tanto, solo puede incluir una de ellas en cualquier operación de zadd:
        • NX: indica a zadd que no actualice componentes existentes. Con esta opción, zadd añadirá únicamente elementos nuevos.
        • XX: indica a zadd a que solo actualice elementos existentes. Con esta opción, zadd nunca añadirá nuevos componentes.
      • CH: en general, zadd solo muestra la cantidad de nuevos elementos añadidos al conjunto ordenado. Con esta opción, sin embargo, zadd mostrará la cantidad de elementos modificados. Esto comprende los componentes recientemente añadidos y aquellos cuya puntuación se modificó.
      • INCR: hace que el comando aumente el valor de la puntuación del componente. Si el componente todavía no existe, el comando lo añadirá al conjunto ordenado con el aumento como puntuación, como si la puntuación original hubiera sido 0. Con INCR incluido, zadd muestra la puntuación nueva del componente si es correcta. Tenga en cuenta que solo puede incluir una puntuación o un componente a la vez cuando se utiliza esta opción.

      En lugar de pasar la opción INCR a zadd, puede usar el comando zincrby, que se comporta exactamente de la misma manera. En vez de dar al componente del conjunto ordenado el valor que indica la puntuación como zadd, aplica a la puntuación del componente un incremento equivalente a ese valor.  Por ejemplo, con el siguiente comando se aplica un incremento de 5 a la puntuación del componente "Stephen Malkmus", que originalmente era 4, con lo cual llega a 9.

      • zincrby faveGuitarists 5 "Stephen Malkmus"

      Output

      "9"

      Como en el caso de la opción INCR del comando zadd, si el componente especificado no existe, zincrby lo crea con el valor de incremento como puntuación.

      Obtener componentes de conjuntos ordenados

      La manera más básica de recuperar componentes de un conjunto ordenado es usar el comando zrange.  Este comando acepta como argumento el nombre de la clave cuyos componentes desea obtener y un intervalo de componentes que se encuentran en su interior. El intervalo está definido por dos números que representan índices basados en cero, lo cual significa que 0 representa el primer componente del conjunto ordenado (o el componente con la puntuación más baja), 1 el siguiente y así sucesivamente.

      En el siguiente ejemplo, se mostrarán los primeros cuatro componentes del conjunto ordenado faveGuitarists creado en la sección anterior:

      • zrange faveGuitarists 0 3

      Output

      1) "Joe Pass" 2) "Rosetta Tharpe" 3) "Bola Sete" 4) "Doug Martsch"

      Tenga en cuenta que si el conjunto ordenado que pasa a zrange tiene dos o más elementos con la misma puntuación, les aplicará orden lexicográfico o alfabético.

      Los índices de inicio y detención también pueden ser números negativos: -1 representa el último componente, -2 el penúltimo y así sucesivamente.

      • zrange faveGuitarists -5 -2

      Output

      1) "Memphis Minnie" 2) "Elizabeth Cotten" 3) "Stephen Malkmus" 4) "Michael Houser"

      zrange puede aceptar el argumento WITHSCORES que, cuando se incluya, también mostrará las puntuaciones de los componentes:

      • zrange faveGuitarists 5 6 WITHSCORES

      Output

      1) "Elizabeth Cotten" 2) "8" 3) "Stephen Malkmus" 4) "9"

      zrange solo puede mostrar un intervalo de componentes en orden numérico ascendente. Para revertir esto y mostrar un intervalo en orden decreciente, debe usar el comando zrevrange. Considere este comando como una reversión temporal del ordenamiento del conjunto ordenado dado antes de mostrar los componentes que se encuentran dentro del intervalo especificado. Como sucede con zrevrange, 0 representará el último componente de la clave, 1 el penúltimo y así sucesivamente:

      • zrevrange faveGuitarists 0 5

      Output

      1) "Nancy Wilson" 2) "Michael Houser" 3) "Stephen Malkmus" 4) "Elizabeth Cotten" 5) "Memphis Minnie" 6) "Doug Martsch"

      zrevrange también puede aceptar la opción WITHSCORES.

      Puede mostrar un intervalo de componentes según sus puntuaciones con el comando zrangebyscore. En el siguiente ejemplo, con el comando se mostrará cualquier componente que se encuentre en la clave faveGuitarists con una puntuación de 2, 3, o 4:

      • zrangebyscore faveGuitarists 2 4

      Output

      1) "Rosetta Tharpe" 2) "Bola Sete" 3) "Doug Martsch" 4) "Memphis Minnie"

      En este ejemplo, el intervalo es inclusivo, lo cual significa que mostrará componentes con puntuaciones de 2 o 4. Puede excluir cualquier extremo del intervalo anteponiéndole un paréntesis abierto ((). En el siguiente ejemplo, se mostrarán todos los componentes con una puntuación superior o igual a 2, pero inferior a 4:

      • zrangebyscore faveGuitarists 2 (4

      Output

      1) "Rosetta Tharpe" 2) "Bola Sete" 3) "Doug Martsch"

      Al igual que zrange, zrangebyscore puede aceptar el argumento WITHSCORES. También acepta la opción LIMIT, que puede usar para obtener solo una selección de elementos del resultado de zrangebyscore. Esta opción acepta un desplazamiento, que indica el primer componente del intervalo que se mostrará con el comando y un recuento que define la cantidad total de componentes que se mostrarán con el comando. Por ejemplo, con el siguiente comando se analizarán los primeros seis componentes del conjunto ordenado faveGuitarists, pero solo se mostrarán 3 componentes de él, a partir del segundo componente del intervalo, representado por 1:

      • zrangebyscore faveGuitarists 0 5 LIMIT 1 3

      Output

      1) "Rosetta Tharpe" 2) "Bola Sete" 3) "Doug Martsch"

      Con el comando zrevrangebyscore, se muestra un intervalo invertido de componentes según sus puntuaciones. Con el siguiente comando se muestran todos los componentes del conjunto con una puntuación de entre 10 y 6:

      • zrevrangebyscore faveGuitarists 10 6

      Output

      1) "Stephen Malkmus" 2) "Elizabeth Cotten"

      Al igual que zrangebyscore, zrangebyscore puede aceptar las opciones WITHSCORES y LIMIT. Además, puede excluir cualquier extremo del intervalo anteponiéndole un paréntesis abierto.

      Puede haber momentos en que todos los componentes de un conjunto ordenado tengan la misma puntuación. En ese caso, puede hacer que Redis muestre de forma forzosa un intervalo de elementos en orden lexicográfico o alfabético con el comando zrangebylex. Para probar este comando, ejecute el siguiente comando zadd a fin de crear un conjunto ordenado en el que cada componente tenga la misma puntuación:

      • zadd SomervilleSquares 0 Davis 0 Inman 0 Union 0 porter 0 magoun 0 ball 0 assembly

      zrangebylex debe ir seguido del nombre de una clave, un intervalo de inicio y un intervalo de detención. Los intervalos de inicio y detención deben iniciarse con un paréntesis abierto (() o un corchete abierto ([), como se muestra a continuación:

      • zrangebylex SomervilleSquares [a [z

      Output

      1) "assembly" 2) "ball" 3) "magoun" 4) "porter"

      Tenga en cuenta que en este ejemplo solo se mostraron cuatro de los ocho componentes del conjunto, a pesar de que el comando buscaba un intervalo de la a a la z. Esto se debe a que los valores de Redis distinguen entre mayúsculas y minúsculas; por lo tanto, los componentes que comienzan con letras mayúsculas se excluyeron de su resultado. Para mostrarlos, puede ejecutar lo siguiente:

      • zrangebylex SomervilleSquares [A [z

      Output

      1) "Davis" 2) "Inman" 3) "Union" 4) "assembly" 5) "ball" 6) "magoun" 7) "porter"

      zrangebylex también acepta los caracteres especiales -, que representa un infinito negativo y +, que representa un infinito positivo. Por lo tanto, con la siguiente sintaxis de comando también se mostrarán todos los componentes del conjunto ordenado:

      • zrangebylex SomervilleSquares - +

      Tenga en cuenta que zrangebylex no puede mostrar componentes del conjunto en orden lexicográfico inverso (alfabético ascendente). Para hacerlo, utilice zrevrangebylex:

      • zrevrangebylex SomervilleSquares + -

      Output

      1) "porter" 2) "magoun" 3) "ball" 4) "assembly" 5) "Union" 6) "Inman" 7) "Davis"

      Debido a que está destinado a usarse con conjuntos ordenados en los que todos los componentes tienen la misma puntuación, zrangebylex no acepta la opción WITHSCORES.  Sin embargo, sí acepta la opción LIMIT.

      Obtener información sobre conjuntos ordenados

      Para averiguar la cantidad de componentes de un conjunto ordenado determinado (o, en otras palabras, su cardinalidad), utilice el comando zcard. En el siguiente ejemplo, se muestra la cantidad de componentes contenidos en la clave faveGuitarists de la primera sección de esta guía:

      Output

      (integer) 9

      zcount puede indicar la cantidad de elementos de un conjunto ordenado determinado que se encuentran dentro de un intervalo de puntuaciones. El primer número que sigue a la clave es el comienzo del intervalo y el segundo es el final:

      • zcount faveGuitarists 3 8

      Output

      (integer) 4

      zscore obtiene la puntuación de un componente especificado de un conjunto ordenado:

      • zscore faveGuitarists "Bola Sete"

      Output

      "3"

      Si el componente o la clave especificados no existen, zscore mostrará (nil).

      zrank es similar a zscore, pero, en vez de mostrar la puntuación del componente determinado, muestra su clasificación. En Redis, una clasificación es un índice basado en cero de los componentes de un conjunto ordenado por su puntuación. Por ejemplo, "Joe Pass" tiene una puntuación de 1, pero, dado que esa es la puntuación más baja de todos los componentes de la clave, tiene una clasificación de 0:

      • zrank faveGuitarists "Joe Pass"

      Output

      (integer) 0

      Hay otro comando de Redis denominado zrevrank que realiza la misma función que zrank, pero, en su lugar, invierte las clasificaciones de los componentes del conjunto. En el siguiente ejemplo, el componente "Joe Pass" tiene la puntuación más baja y, por lo tanto, la clasificación invertida más alta:

      • zrevrank faveGuitarists "Joe Pass"

      Output

      (integer) 8

      La única relación entre la puntuación de un componente y su clasificación es la posición que ocupa su puntuación en relación con las de otros miembros.  Si hay una brecha de puntuación entre dos componentes secuenciales, no se reflejará en su clasificación. Tenga en cuenta que si dos componentes tienen la misma puntuación, el primero en orden alfabético tendrá la menor clasificación.

      Al igual que zscore, zrank y zrevrank devolverán (nil) si la clave o el componente no existen.

      zlexcount puede indicar la cantidad de componentes que se encuentran en un conjunto ordenado en un intervalo lexicográfico. En el siguiente ejemplo, se utiliza el conjunto ordenado SomervilleSquares de la sección anterior:

      • zlexcount SomervilleSquares [M [t

      Output

      (integer) 5

      Este comando tiene la misma sintaxis que zrangebylex. Por lo tanto, consulte la sección anterior para obtener información detallada sobre cómo definir un intervalo de cadena.

      Eliminar componentes de conjuntos ordenados

      Con el comando zrem, es posible eliminar uno o más componentes de un conjunto ordenado:

      • zrem faveGuitarists "Doug Martsch" "Bola Sete"

      zrem mostrará un entero que indicará la cantidad de componentes que eliminó del conjunto ordenado:

      Output

      (integer) 2

      Hay tres comandos de Redis que le permiten eliminar componentes de un conjunto ordenado basado en un intervalo. Por ejemplo, si todos los componentes de un conjunto ordenado tienen la misma puntuación, puede eliminar componentes sobre la base de un intervalo lexicográfico con zremrangebylex. Este comando utiliza la misma sintaxis que zrangebylex. En el siguiente ejemplo, se eliminarán de la clave SomervilleSquares creada en la sección anterior todos los componentes que comiencen con una letra mayúscula :

      • zremrangebylex SomervilleSquares [A [Z

      zremrangebylex dará como resultado un entero que indica la cantidad de componentes que eliminó:

      Output

      (integer) 3

      También puede eliminar componentes en base a un intervalo de puntuaciones con el comando zremrangebyscore, que utiliza la misma sintaxis que el comando zrangebyscore. En el siguiente ejemplo, se eliminarán todos los componentes de faveGuitarists con una puntuación de 4, 5 o 6:

      • zremrangebyscore faveGuitarists 4 6

      Output

      (integer) 1

      Puede eliminar componentes de un conjunto en base a un intervalo de clasificaciones con el comando zremrangebyrank, que utiliza la misma sintaxis que zrangebyrank. Con el siguiente comando, se eliminarán los tres componentes del conjunto ordenado con las clasificaciones más bajas, que se definen en función de un intervalo de índices basados en cero:

      • zremrangebyrank faveGuitarists 0 2

      Output

      (integer) 3

      Tenga en cuenta que los números que se pasan a remrangebyrank también pueden ser negativos: -1 representa la clasificación más alta, -2 la siguiente y así sucesivamente.

      Crear nuevos conjuntos ordenados a partir de conjuntos existentes

      Redis incluye dos comandos que le permiten comparar componentes de varios conjuntos ordenados y crear conjuntos nuevos sobre la base de esas comparaciones: estos son zinterstore y zunionstore. Para experimentar con ellos, ejecute los siguientes comandos zadd a fin de crear conjuntos ordenados de ejemplo.

      • zadd NewKids 1 "Jonathan" 2 "Jordan" 3 "Joey" 4 "Donnie" 5 "Danny"
      • zadd Nsync 1 "Justin" 2 "Chris" 3 "Joey" 4 "Lance" 5 "JC"

      zinterstore encuentra los componentes que comparten dos o más conjuntos ordenados (en su intersección) y produce un nuevo conjunto ordenado que contiene únicamente estos componentes. Este comando debe incluir, en orden, el nombre de una clave de destino en la que los componentes de la intersección se almacenarán como conjunto ordenado, el número de claves que se pasan a zinterstore y los nombres de las claves que desea analizar:

      • zinterstore BoyBands 2 NewKids Nsync

      zinterstore mostrará un entero que indica la cantidad de elementos almacenados en el conjunto ordenado de destino. Debido a que NewKids y Nsync solo comparten un componente, "Joey", el comando mostrará 1:

      Output

      (integer) 1

      Tenga en cuenta que si la clave de destino ya existe, zinterstore sobrescribirá su contenido.

      zunionstore creará un nuevo conjunto ordenado que contendrá todos los componentes de las claves que se le pasaron. Este comando utiliza la misma sintaxis que zinterstore y requiere el nombre de una clave de destino, la cantidad de claves que se pasan al comando y los nombres de estas:

      • zunionstore SuperGroup 2 NewKids Nsync

      Al igual que zinterstore, zunionstore , mostrará un entero que indica la cantidad de elementos almacenados en la clave de destino. Si bien los dos conjuntos ordenados originales tienen cinco componentes, dado que los conjuntos ordenados no pueden tener componentes repetidos y cada clave tiene un componente denominado "Joey", el entero resultante será 9:

      Output

      (integer) 9

      Al igual que zinterstore, zunionstore sobrescribirá el contenido de la clave de destino si ya existe.

      Para tener más control sobre las puntuaciones de los componentes al crear conjuntos ordenados nuevos con zinterstore y zunionstore, los dos comandos aceptan las opciones WEIGHTS y AGGREGATE.

      La opción WEIGHTS va seguida de un número por cada conjunto ordenado incluido en el comando que pondera o multiplica la puntuación de cada componente. El primer número después de la opción WEIGHTS pondera las puntuaciones de la primera clave que se pasó al comando, el segundo número pondera la segunda y así sucesivamente.

      En el siguiente ejemplo, se crea un nuevo conjunto ordenado que contiene las claves intersecantes de los conjuntos ordenados NewKids y Nsync. Pondera las puntuaciones de la clave de NewKids en un factor de tres y las de la clave de Nsync en un factor de siete:

      • zinterstore BoyBandsWeighted 2 NewKids Nsync WEIGHTS 3 7

      Si la opción WEIGHTS no se incluye, la ponderación por defecto es 1 tanto para zinterstore como para zunionstore.

      AGGREGATE acepta tres subopciones. La primera, SUM, implementa el comportamiento predeterminado de zinterstore y zunionstore añadiendo las puntuaciones de los componentes coincidentes en los conjuntos combinados.

      Si ejecuta una operación zinterstore o zunionstore en dos conjuntos ordenados que comparten un componente, pero este tiene una puntuación diferente en cada conjunto, puede hacer que la operación asigne por la fuerza la menor de las dos puntuaciones en el nuevo conjunto con la subopción MIN.

      • zinterstore BoyBandsWeightedMin 2 NewKids Nsync WEIGHTS 3 7 AGGREGATE MIN

      Debido a que los dos conjuntos ordenados solo tienen un componente coincidente con la misma puntuación (3), este comando creará un nuevo conjunto con el componente que tenga la menor de las dos puntuaciones ponderadas:

      • zscore BoyBandsWeightedMin "Joey"

      Output

      "9"

      De la misma manera, AGGREGATE puede forzar zinterstore o zunionstore a asignar la mayor de las dos puntuaciones con la opción MAX:

      • zinterstore BoyBandsWeightedMax 2 NewKids Nsync WEIGHTS 3 7 AGGREGATE MAX

      A través de este comando, se crea un nuevo conjunto con un componente, "Joey", que tiene la mayor de las dos puntuaciones ponderadas.

      • zscore BoyBandsWeightedMax "Joey"

      Output

      "21"

      Puede ser útil considerar a WEIGHTS como una alternativa para manipular las puntuaciones de los componentes temporalmente antes de que se analicen. De la misma manera, es útil concebir a la opción AGGREGATE como una opción para decidir cómo controlar las puntuaciones de los componentes antes de añadirlos a sus nuevos conjuntos.

      Conclusión

      En esta guía, se detallan varios comandos que se utilizan para crear y administrar conjuntos ordenados en Redis. Si desea ver en esta guía descripciones de otros comandos, argumentos o procedimientos relacionados, deje sus solicitudes o sugerencias en la sección de comentarios a continuación.

      Para obtener más información sobre los comandos de Redis, consulte nuestra serie de tutoriales Cómo administrar bases de datos de Redis.



      Source link

      Cómo administrar y usar activadores de bases de datos de MySQL en Ubuntu 18.04


      El autor seleccionó la Apache Software Foundation para recibir una donación como parte del programa Write for DOnations.

      Introducción

      En MySQL, un activador es un comando SQL definido por el usuario que se invoca automáticamente durante una operación INSERT, DELETE o UPDATE. El código de activación se asocia con una tabla y se destruye una vez que se elimina una tabla. Puede especificar un tiempo de acción de activación y establecer si esta se producirá antes o después del evento de base de datos definido.

      Los activadores tienen varias ventajas. Por ejemplo, puede usarlos para generar el valor de una columna derivada durante una instrucción INSERT. Otro caso de uso tiene que ver con la aplicación de la integridad referencial, en el que puede usar un activador para guardar un registro en varias tablas relacionadas. Entre otras ventajas, se incluyen el registro de las acciones del usuario para realizar una auditoría de las tablas, así como la copia en vivo de datos en diferentes esquemas de bases de datos por motivos de redundancia para evitar un único punto de fallo.

      También puede usar activadores para mantener las reglas de validación en el nivel de base de datos. Esto le permite compartir la fuente de datos en varias aplicaciones sin infringir la lógica de negocios. Con esto, se reducen en gran medida los recorridos de ida y vuelta al servidor de base de datos, lo cual a su vez mejora el tiempo de respuesta de sus aplicaciones. Debido a que en el servidor de base de datos se ejecutan activadores, se pueden aprovechar recursos mejorados de este, como la memoria RAM y el CPU.

      En este tutorial, creará, usará y eliminará diferentes tipos de activadores en su base de datos de MySQL.

      Requisitos previos

      Antes de comenzar, asegúrese de contar con lo siguiente:

      Paso 1: Crear una base de datos de ejemplo

      En este paso, creará una base de datos de clientes de ejemplo con varias tablas para demostrar el funcionamiento de los activadores de MySQL.

      Para obtener más información sobre consultas de MySQL, lea nuestra Introducción a las consultas de MySQL.

      Primero, inicie sesión en su servidor MySQL como root:

      Introduzca su contraseña root de MySQL cuando se le solicite y presione INTRO para continuar. Cuando visualice el intérprete de comandos de mysql>, ejecute el siguiente comando para crear una base de datos test_db:

      Output

      Query OK, 1 row affected (0.00 sec)

      A continuación, realice un cambio a test_db con lo siguiente:

      Output

      Database changed

      Comience creando una tabla customers. En esta tabla se almacenarán los registros de los clientes, incluidos customer_id, customer_name y level. Habrá dos niveles de cliente: BASIC y VIP.

      • Create table customers(customer_id BIGINT PRIMARY KEY, customer_name VARCHAR(50), level VARCHAR(50) ) ENGINE=INNODB;

      Output

      Query OK, 0 rows affected (0.01 sec)

      Ahora, añada algunos registros a la tabla customers. Para hacer esto, ejecute los siguientes comandos uno por uno:

      • Insert into customers (customer_id, customer_name, level )values('1','JOHN DOE','BASIC');
      • Insert into customers (customer_id, customer_name, level )values('2','MARY ROE','BASIC');
      • Insert into customers (customer_id, customer_name, level )values('3','JOHN DOE','VIP');

      Verá el siguiente resultado después de ejecutar cada uno de los comandos INSERT:

      Output

      Query OK, 1 row affected (0.01 sec)

      Para asegurarse de que los registros de ejemplo se hayan insertado correctamente, ejecute el comando SELECT:

      Output

      +-------------+---------------+-------+ | customer_id | customer_name | level | +-------------+---------------+-------+ | 1 | JOHN DOE | BASIC | | 2 | MARY ROE | BASIC | | 3 | JOHN DOE | VIP | +-------------+---------------+-------+ 3 rows in set (0.00 sec)

      También creará otra tabla para contener información relacionada con la cuenta customers. Esta tabla contendrá un campo customer_id y un campo status_notes.

      Ejecute el siguiente comando:

      • Create table customer_status(customer_id BIGINT PRIMARY KEY, status_notes VARCHAR(50)) ENGINE=INNODB;

      A continuación, creará una tabla sales. En esta tabla, se almacenarán datos de ventas relacionados con los diferentes clientes a través de la columna customer_id:

      • Create table sales(sales_id BIGINT PRIMARY KEY, customer_id BIGINT, sales_amount DOUBLE ) ENGINE=INNODB;

      Output

      Query OK, 0 rows affected (0.01 sec)

      En los próximos pasos, añadirá datos de ejemplo a los de sales mientras prueba los activadores. A continuación, cree una tabla audit_log para registrar las actualizaciones realizadas en la tabla sales cuando implemente el activador AFTER UPDATE en el paso 5:

      • Create table audit_log(log_id BIGINT PRIMARY KEY AUTO_INCREMENT, sales_id BIGINT, previous_amount DOUBLE, new_amount DOUBLE, updated_by VARCHAR(50), updated_on DATETIME ) ENGINE=INNODB;

      Output

      Query OK, 0 rows affected (0.02 sec)

      Una vez establecidas la base de datos test_db y las cuatro tablas, procederá a trabajar con los diferentes activadores de MySQL en su base de datos.

      Paso 2: Crear un activador “Before Insert”

      En este paso, examinará la sintaxis de un activador de MySQL antes de aplicar esta lógica para crear un activador BEFORE INSERT que valide el campo sales_amount cuando se inserten datos en la tabla sales.

      La sintaxis general para crear un activador de MySQL se muestra en el siguiente ejemplo:

      DELIMITER //
      CREATE TRIGGER [TRIGGER_NAME]
      [TRIGGER TIME] [TRIGGER EVENT]
      ON [TABLE]
      FOR EACH ROW
      [TRIGGER BODY]//
      DELIMITER ;
      

      En la estructura del activador se incluye lo siguiente:

      DELIMITER //: el delimitador predeterminado de MySQL es ;, es necesario cambiarlo por algo diferente para que MySQL trate las siguientes líneas como un comando hasta que alcance su delimitador personalizado. En este ejemplo, el delimitador se cambió a // y luego al final se redefinió el delimitador ;.

      [TRIGGER_NAME]: un activador debe contar con un nombre y aquí es donde debe incluir el valor.

      [TRIGGER TIME]: un activador se puede invocar en diferentes intervalos. En MySQL se le permite definir si el activador se iniciará antes o después de una operación de base de datos.

      [TRIGGER EVENT]: los activadores solo se pueden invocar con operaciones INSERT, UPDATE y DELETE. Aquí puede usar cualquier valor dependiendo de lo que quiera lograr.

      [TABLE]: cualquier activador que cree en su base de datos de MySQL debe estar asociado a una tabla.

      FOR EACH ROW: con esta instrucción se ordena a MySQL ejecutar el código de activación para cada fila afectada por el activador.

      [TRIGGER BODY]: el código que se ejecuta cuando se invoca el activador se conoce como cuerpo del activador. Puede constar de una sola instrucción SQL o de varios comandos. Tenga en cuenta que si ejecuta varias instrucciones SQL en el cuerpo del activador, debe ajustarlas entre un bloque BEGIN... END.

      Nota: Cuando cree el cuerpo del activador, puede usar las palabras claves OLD y NEW para acceder a los valores antiguos y nuevos de la columna introducidos durante una operación INSERT, UPDATE, y DELETE. En un activador DELETE, solo se puede emplear la palabra clave OLD (que usará en el paso 4).

      Ahora, creará su primer activador BEFORE INSERT. Este activador estará asociado con la tabla sales y se invocará antes de que se inserte un registro para validar sales_amount. La función del activador es verificar si el campo sales_amount que se inserta en la tabla “sales” es mayor que 10000 y mostrar un error si esto se evalúa a “true”.

      Asegúrese de haber iniciado sesión en el servidor de MySQL. Luego, introduzca los siguientes comandos MySQL uno por uno:

      • DELIMITER //
      • CREATE TRIGGER validate_sales_amount
      • BEFORE INSERT
      • ON sales
      • FOR EACH ROW
      • IF NEW.sales_amount>10000 THEN
      • SIGNAL SQLSTATE '45000'
      • SET MESSAGE_TEXT = 'Sale has exceeded the allowed amount of 10000.';
      • END IF//
      • DELIMITER ;

      Usará la instrucción IF...THEN...END IF para evaluar si la cantidad que se proporciona durante la instrucción INSERT se encuentra dentro de su rango. Con el activador se puede extraer el nuevo valor sales_amount proporcionado con la palabra clave NEW.

      Para mostrar un mensaje de error genérico, utilice las siguientes líneas a fin de informar al usuario sobre el error:

      SIGNAL SQLSTATE '45000'
      SET MESSAGE_TEXT = 'Sale has exceeded the allowed amount of 10000.';
      

      A continuación, inserte un registro con un sales_amount de 11000 en la tabla sales para verificar si con el activador se detendrá la operación:

      • Insert into sales(sales_id, customer_id, sales_amount) values('1','1','11000');

      Output

      ERROR 1644 (45000): Sale has exceeded the allowed amount of 10000.

      Este error muestra que el código de activación funciona según lo previsto.

      Ahora, pruebe un nuevo registro con un valor de 7500 para verificar si el comando tendrá éxito:

      • Insert into sales(sales_id, customer_id, sales_amount) values('1','1','7500');

      Debido a que el valor se encuentra dentro del rango recomendado, verá el siguiente resultado:

      Output

      Query OK, 1 row affected (0.01 sec)

      Para confirmar que se insertaron los datos, ejecute el siguiente comando:

      En el resultado, se confirma que los datos se encuentran en la tabla:

      Output

      +----------+-------------+--------------+ | sales_id | customer_id | sales_amount | +----------+-------------+--------------+ | 1 | 1 | 7500 | +----------+-------------+--------------+ 1 row in set (0.00 sec)

      En este paso, probó activadores para validar datos antes de su inserción en una base de datos.

      A continuación, trabajará con el activador AFTER INSERT para guardar información relacionada en diferentes tablas.

      Paso 3: Crear un activador “After Insert”

      Los activadores AFTER INSERT se ejecutan cuando se insertan registros correctamente en una tabla. Esta funcionalidad puede utilizarse para ejecutar automáticamente otras lógicas relacionadas con los negocios. Por ejemplo, en una aplicación bancaria, con un activador AFTER INSERT se puede cerrar una cuenta de préstamo cuando un cliente termina de pagarlo. El activador puede controlar todos los pagos introducidos en una tabla de transacciones y cerrar el préstamo automáticamente una vez que el saldo llegue a cero.

      En este paso, trabajará con su tabla customer_status usando un activador AFTER INSERT para ingresar registros de clientes relacionados.

      Para crear el activador AFTER INSERT, introduzca los siguientes comandos:

      • DELIMITER //
      • CREATE TRIGGER customer_status_records
      • AFTER INSERT
      • ON customers
      • FOR EACH ROW
      • Insert into customer_status(customer_id, status_notes) VALUES(NEW.customer_id, 'ACCOUNT OPENED SUCCESSFULLY')//
      • DELIMITER ;

      Output

      Query OK, 0 rows affected (0.00 sec)

      Aquí, indica que MySQL guarde otro registro en la tabla customer_status una vez que se inserte un nuevo registro de cliente en la tabla customers.

      Ahora, inserte un nuevo registro en la tabla customers para confirmar que se invocará su código de activación.

      • Insert into customers (customer_id, customer_name, level )values('4','DAVID DOE','VIP');

      Output

      Query OK, 1 row affected (0.01 sec)

      Debido a que el registro se insertó correctamente, compruebe que se haya introducido un nuevo registro de estado en la tabla customer_status:

      • Select * from customer_status;

      Output

      +-------------+-----------------------------+ | customer_id | status_notes | +-------------+-----------------------------+ | 4 | ACCOUNT OPENED SUCCESSFULLY | +-------------+-----------------------------+ 1 row in set (0.00 sec)

      En el resultado se confirma que el activador se ejecutó correctamente.

      El activador AFTER INSERT es útil para controlar el ciclo de vida de un cliente. En un entorno de producción, las cuentas de los clientes pueden atravesar diferentes etapas, como la apertura, la suspensión y el cierre.

      En los siguientes pasos, trabajará con activadores UPDATE.

      Paso 4: Crear un activador “Before Update”

      Los activadores BEFORE UPDATE son similares a los BEFORE INSERT; la diferencia radica en el momento en que se invocan. Puede usar el activador BEFORE UPDATE para verificar una lógica de negocios antes de que se actualice un registro. Para probar esto, usará la tabla customers en la que ya insertó datos.

      Dispone de dos niveles para sus clientes en la base de datos. En este ejemplo, una vez que la cuenta de un cliente asciende al nivel VIP, ya no es posible que descienda al nivel BASIC. Para aplicar tal regla, creará un activador BEFORE UPDATE que se ejecutará antes de la instrucción UPDATE, como se muestra a continuación. Si un usuario de la base de datos intenta hacer que un cliente descienda al nivel BASIC desde el nivel VIP, se activará una excepción definida por el usuario.

      Introduzca los siguientes comandos SQL uno por uno para crear el activador BEFORE UPDATE:

      • DELIMITER //
      • CREATE TRIGGER validate_customer_level
      • BEFORE UPDATE
      • ON customers
      • FOR EACH ROW
      • IF OLD.level='VIP' THEN
      • SIGNAL SQLSTATE '45000'
      • SET MESSAGE_TEXT = 'A VIP customer can not be downgraded.';
      • END IF //
      • DELIMITER ;

      Utilice la palabra clave OLD para capturar el nivel que el usuario proporciona cuando ejecuta el comando UPDATE. Una vez más, utilice la instrucción IF...THEN…END IF“ para indicar una instrucción de error genérico al usuario.

      Luego, ejecute el siguiente comando SQL con el que se intenta bajar el nivel de la cuenta de un usuario asociado con el customer_id de 3:

      • Update customers set level='BASIC' where customer_id='3';

      Verá el siguiente resultado, en el que se muestra SET MESSAGE_TEXT:

      Output

      ERROR 1644 (45000): A VIP customer can not be downgraded.

      Si ejecuta el mismo comando en un cliente de nivel BASIC e intenta que la cuenta ascienda al nivel VIP, el comando se ejecutará correctamente:

      • Update customers set level='VIP' where customer_id='1';

      Output

      Rows matched: 1 Changed: 1 Warnings: 0

      Usó el activador BEFORE UPDATE para implementar una regla comercial. Ahora, usará un activador AFTER UPDATE para registros de auditoría.

      Paso 5: Crear un activador “After Update”

      Un activador AFTER UPDATE se invoca una vez que se actualiza correctamente el registro de una base de datos. Este comportamiento hace que el activador sea adecuado para los registros de auditoría. En un entorno multiusuario, es posible que el administrador quiera ver el historial de los usuarios que actualizan registros en una tabla en particular para auditorías.

      Creará un activador que registre la actividad de actualización de la tabla sales. Nuestra tabla audit_log contendrá información sobre los usuarios de MySQL que actualicen la tabla sales, la date de la actualización y los valores sales_amount de new y old.

      Para crear el activador, ejecute los siguientes comandos SQL:

      • DELIMITER //
      • CREATE TRIGGER log_sales_updates
      • AFTER UPDATE
      • ON sales
      • FOR EACH ROW
      • Insert into audit_log(sales_id, previous_amount, new_amount, updated_by, updated_on) VALUES (NEW.sales_id,OLD.sales_amount, NEW.sales_amount,(SELECT USER()), NOW() )//
      • DELIMITER ;

      Se ingresa un nuevo registro en la tabla audit_log. Utilice la palabra clave NEW para obtener el valor de sales_id y el nuevo sales_amount. Además, utilice la palabra clave OLD para obtener el sales_amount anterior, ya que desea registrar ambos montos para auditoría.

      Con el comando SELECT USER() se obtiene el usuario actual que realiza la operación y con la instrucción NOW() se obtiene el valor de la fecha y hora actuales del servidor de MySQL.

      Si ahora un usuario intenta actualizar el valor de cualquier registro en la tabla sales, el activador log_sales_updates insertará un nuevo registro en la tabla audit_log.

      Crearemos un nuevo registro de ventas con un sales_id aleatorio de 5 e intentaremos actualizarlo. Primero, inserte el registro de ventas con lo siguiente:

      • Insert into sales(sales_id, customer_id, sales_amount) values('5', '2','8000');

      Output

      Query OK, 1 row affected (0.00 sec)

      A continuación, actualice el registro:

      • Update sales set sales_amount='9000' where sales_id='5';

      Verá el siguiente resultado:

      Output

      Rows matched: 1 Changed: 1 Warnings: 0

      Ahora ejecute el siguiente comando para verificar si con el activador AFTER UPDATE se pudo introducir un nuevo registro en la tabla audit_log:

      En el activador se registró la actualización. En el resultado se muestran el sales_amount y el new amount anteriores registrados con el usuario que actualizó los registros:

      Output

      +--------+----------+-----------------+------------+----------------+---------------------+ | log_id | sales_id | previous_amount | new_amount | updated_by | updated_on | +--------+----------+-----------------+------------+----------------+---------------------+ | 1 | 5 | 8000 | 9000 | root@localhost | 2019-11-07 09:28:36 | +--------+----------+-----------------+------------+----------------+---------------------+ 1 row in set (0.00 sec)

      También dispone de la fecha y hora en las que se realizó la actualización, que son valiosas para auditorías.

      A continuación, usará el activador DELETE para aplicar la integridad referencial a nivel de base de datos.

      Paso 6: Crear un activador “Before Delete”

      Los activadores BEFORE DELETE se invocan antes de que se ejecute una instrucción DELETE en una tabla. Estos tipos de activadores normalmente se utilizan para implementar la integridad referencial en diferentes tablas relacionadas. Por ejemplo, cada registro de la tabla sales se relaciona a un customer_id de la tabla customers. Si un usuario de la base de datos eliminara un registro de la tabla customers que tiene un registro relacionado en la tabla sales, usted no tendría manera de conocer al cliente asociado a ese registro.

      A fin de evitar esto, puede crear un activador BEFORE DELETE para aplicar su lógica. Ejecute los siguientes comandos SQL uno por uno:

      • DELIMITER //
      • CREATE TRIGGER validate_related_records
      • BEFORE DELETE
      • ON customers
      • FOR EACH ROW
      • IF OLD.customer_id in (select customer_id from sales) THEN
      • SIGNAL SQLSTATE '45000'
      • SET MESSAGE_TEXT = 'The customer has a related sales record.';
      • END IF//
      • DELIMITER ;

      Ahora, intente eliminar un cliente que tenga un registro de ventas relacionado:

      • Delete from customers where customer_id='2';

      Como resultado, obtendrá lo siguiente:

      Output

      ERROR 1644 (45000): The customer has a related sales record.

      Con el activador BEFORE DELETE se puede evitar la eliminación accidental de información relacionada en una base de datos.

      Sin embargo, en algunas situaciones, es posible que quiera eliminar todos los registros asociados con un registro específico de las diferentes tablas relacionadas. En este caso, usaría el activador AFTER DELETE, que probará en el siguiente paso.

      Paso 7: Crear un activador “After Delete”

      Los activadores AFTER DELETE funcionan una vez que se elimina correctamente un registro. Un ejemplo de cómo puede usar un activador AFTER DELETE es una situación en la cual el nivel de descuento que recibe un cliente en particular se determina mediante el número de ventas realizadas durante un período definido. Si alguno de los registros del cliente se eliminan de la tabla sales, el nivel de descuento de este deberá reducirse.

      Otro uso del activador AFTER DELETE consiste en eliminar información relacionada de otra tabla una vez que se elimina un registro de una tabla básica. Por ejemplo, establecerá un activador con el que se elimine el registro del cliente si los registros de ventas con los customer_id relacionados se eliminan de la tabla sales. Ejecute el siguiente comando para crear su activador:

      • DELIMITER //
      • CREATE TRIGGER delete_related_info
      • AFTER DELETE
      • ON sales
      • FOR EACH ROW
      • Delete from customers where customer_id=OLD.customer_id;//
      • DELIMITER ;

      A continuación, ejecute lo siguiente para eliminar todos los registros de ventas asociados con un customer_id de 2:

      • Delete from sales where customer_id='2';

      Output

      Query OK, 1 row affected (0.00 sec)

      Ahora compruebe si hay registros para el cliente en la tabla sales:

      • Select * from customers where customer_id='2';

      Obtendrá un resultado Empty Set, ya que el activador eliminó el registro del cliente asociado con el customer_id de 2:

      Output

      Empty set (0.00 sec)

      Con esto, habrá usado cada una de las diferentes formas de activadores para realizar funciones específicas. A continuación, verá la manera de eliminar un activador de la base de datos si ya no lo necesita.

      Paso 8: Eliminar activadores

      Con un método similar al que se emplea para cualquier otro objeto de base de datos, puede eliminar los activadores usando el comando DROP. A continuación, se muestra la sintaxis para eliminar un activador:

      Drop trigger [TRIGGER NAME];
      

      Por ejemplo, para eliminar el último activador AFTER DELETE que creó, ejecute el siguiente comando:

      • Drop trigger delete_related_info;

      Output

      Query OK, 0 rows affected (0.00 sec)

      La necesidad de eliminar los activadores surge cuando desea recrear su estructura. En tal caso, puede eliminar el activador y redefinir uno nuevo con los diferentes comandos de activación.

      Conclusión

      A través de este tutorial, creó, utilizó y eliminó los diferentes tipos de activadores de una base de datos de MySQL. Usando un ejemplo de base de datos relacionada con los clientes, implementó activadores para diferentes casos de uso, como la validación de datos, la aplicación de lógica de negocios, el registro de auditorías y la aplicación de integridad referencial.

      Para obtener más información sobre el uso de su base de datos de MySQL, consulte lo siguiente:



      Source link