Sesión 10. SQL Sublenguaje DCL Objetivos de la clase Reconocer el implementar las sentencias del sublenguaje DCL. Identificar en qué situación usar cada sentencia. Temario 09 10 Triggers + Workshop DML Sublenguajes DCL y TCL ✓ Triggers ✓ Lenguaje DCL ✓ Sintaxis ✓ ✓ Integración de funciones Gestionar usuarios ✓ Workshop ✓ Sublenguaje TCL ✓ Transacciones 11 Backup y restauración + Workshop DCL y TCL ✓ Backup ✓ Restauración ✓ Workshop MAPA DE CONCEPTOS Create User Usuarios Rename User Drop User Lenguaje DCL Grant Privileges Permisos Revoque Privileges El lenguaje DCL Concepto general Data Control Language El Lenguaje de Control de Datos (DCL) permite definir diferentes usuarios dentro del motor de base de datos MySQL, y establecer para cada uno de ellos, permisos totales, parciales, o negar el acceso sobre los diferentes objetos que conforman la Base de Datos. Data Control Language Al igual que con DDL y DML, DCL provee una serie de cláusulas y comandos para poder crear, renombrar y eliminar usuarios dentro de uno o más servidores de base de datos, como así también establecer y/o modificar un password o contraseña de acceso. Data Control Language Definidos los usuarios a través de DCL, contamos con otro set de comandos y cláusulas para permitir o revocar el acceso a diferentes Objetos de la base de datos. Entendemos por Objetos a: Tablas, Campos, Vistas, Stored Procedures y Funciones Almacenadas. Base de datos del sistema DB de sistema MySQL cuenta con lo que se conoce como Base de Datos del Sistema, donde se almacena información referente al motor de base de datos en sí, performance y demás cuestiones propias de un sistema de software. DB de sistema Cuando instalamos por primera vez MySQL vemos que, por defecto, se crea la base de datos SYS junto al motor de Mysql. Despleguemos la misma para ver su contenido. DB de sistema Veremos que apenas tiene una tabla visible, llamada sys_config, con información sobre performance de carga. Si revisamos las Vistas y los Stored Procedures, encontraremos mucho más datos que aportan a la misma causa. DB de sistema Además de sys, MySQL tiene otra base de datos de sistema llamada mysql. En la misma encontrarás otro set de tablas con información general para el sistema MySQL, más una tabla llamada user, donde se almacena la información de usuarios de la o las bases de datos de MySQL. DB de sistema Puedes verificar esto mismo, directamente desde MySQL Workbench, abriendo una pestaña de script y escribiendo los comandos: USE mysql; SHOW tables; La tabla mysql.user La tabla mysql.user En la tabla user, Mysql almacena la información de usuarios junto a cada uno de los permisos o Sesióno para trabajar sobre la base de datos Mysql y los objetos de ésta. La tabla mysql.user Si invocamos la misma mediante la instrucción SELECT, veremos información sobre el host o máquina, el usuario en cuestión, y la lista de permisos totales que podemos aplicar sobre cada usuario. La tabla mysql.user En esta imagen podemos ver los Campos que definen los permisos de usuario sobre DML. Cada permiso se define con un Y o N, si queremos brindarle al usuario Acceso o Restricción (respectivamente), sobre una acción determinada Gestionar usuarios Gestionar usuarios Veamos a continuación, cómo gestionar nuestros propios usuarios dentro de Mysql a través de los diferentes comandos que este motor de base de datos pone a nuestra disposición. Create user Create user A través de la sentencia CREATE USER ‘nombre’, creamos un nuevo usuario en la base de datos. Podemos definir solo su nombre, o el nombre de éste seguido del dominio al cual pertenece. CREATE USER ‘prueba@dominio’; Create user+dominio El dominio en sí hace referencia a la máquina o computadora donde se encuentra instalado Mysql. Podemos referirnos a ésta mediante su nombre, IP, o si es local, utilizando localhost. CREATE USER ‘prueba@dbProdServer’; //su nombre CREATE USER ‘prueba@192.168.0.213; //su dirección IP CREATE USER ‘prueba@localhost’; //local Create user+dominio+password Si también deseamos especificar un password para el usuario en cuestión, podemos hacerlo incorporando a la sentencia, el comando IDENTIFIED BY. El password será visible en el comando en cuestión, pero se encriptará una vez almacenado en la tabla user. CREATE USER ‘prueba@localhost’ IDENTIFIED BY ‘miPassword’; Create user La columna authentication_string permite validar que, el password ingresado, se almacena de manera encriptada. Modificar un password Modificar un password Podemos cambiar el password de un usuario, mediante el comando ALTER USER: ALTER USER ‘prueba@dominio’ IDENTIFIED BY ‘nuevoPassword’; También podemos hacerlo mediante la sentencia UPDATE: UPDATE mysql.user SET Password=PASSWORD(‘nuevoPassword’)’ WHERE user = ‘prueba’ AND host = ‘dominio’; Modificar un password Si en algún momento debemos trabajar con una base de datos Mysql v5.7.5 o inferior, debemos utilizar el comando SET PASSWORD. SET PASSWORD FOR ‘prueba@dominio’ = PASSWORD(‘nuevoPassword’); o para el usuario logeado SET PASSWORD = PASSWORD(‘nuevoPassword’) Renombrar y eliminar usuarios Renombrar un usuario También podemos renombrar un usuario, una vez creado, utilizando el comando RENAME USER. RENAME USER ‘prueba@localhost’ TO UANL@dominio; Eliminar un usuario Finalmente, si debemos eliminar un usuario, recurrimos al comando DROP USER: DROP USER ‘usuario@dominio’; Ejemplo en vivo Implementaremos las sentencias create, drop y rename user. Permisos definidos por defecto Por cada usuario que creamos, solo definimos un nombre de usuario y sobre qué servidor trabajará el mismo. Nos queda por delante comenzar a definir los permisos que cada usuario tendrá, sobre un dominio, base de datos, tabla(s) y/o campo(s) específicos. ¡Veamos entonces cómo hacerlo! Verificar el usuario creado Paso 1 Si queremos verificar los permisos de un usuario específico, podemos realizar una consulta de selección filtrando específicamente por el usuario en cuestión. Paso 2 Ejecutemos para ello, la sentencia SELECT sobre la tabla user, filtrando por el usuario en particular: SELECT * FROM mysql.user WHERE user LIKE ‘UANL%’; Paso 3 Como podemos apreciar, en cada campo de la tabla, el parámetro correspondiente al permiso está seteado en N, lo cual indica que no tiene establecido ningún permiso. Establecer permisos sobre objetos MySQL Sentencia Grant Sentencia Grant A través de sentencia GRANT, podemos definir en detalle, los permisos de escritura, modificación, eliminación, y/o lectura de datos y creación, alteración y borrado de objetos de la base de datos, para un usuario Sentencia Grant SHOW GRANTS nos permite detallar sobre el usuario específico, cuáles permisos tiene asociado sobre los diferentes objetos de la DB. SHOW GRANTS FOR ‘UANL@dominio’; Sentencia Grant Su resultado no detalla ningún permiso sobre sentencias DML, aún para el usuario seleccionado. Veamos entonces cómo comenzar a otorgarlos. SHOW GRANTS FOR ‘UANL@dominio’; Otorgar todos los permisos Otorgarle todos los permisos Para otorgarle permisos completos a un usuario, sobre todos los objetos de todos los dominios, utilizamos la sentencia GRANT ALL. GRANT ALL ON *.* TO ‘UANL@dominio’; El uso de *.* refiere a objetos.dominio Otorgarle todos los permisos A través de la pestaña Action Output veremos la correcta aplicación de los permisos sobre el usuario referenciado. GRANT ALL ON *.* TO ‘UANL@dominio’; Otorgar permisos sobre tabla(s) Otorgar permisos sobre una tabla Para otorgarle permisos a un usuario sobre una tabla específica de una base de datos puntual, debemos referenciar la sentencia de la siguiente forma: GRANT ALL ON gamer.level_game TO ‘UANL@localhost’; Permisos en más de una tabla Deberemos definir una línea específica por cada tabla en la que un usuario específico tendrá permisos: GRANT ALL ON gamer.class TO ‘UANL@localhost’; GRANT ALL ON gamer.game TO ‘UANL@localhost’; Otorgar permisos selectivos Otorgar permisos selectivos Si por ejemplo deseamos que un usuario tenga permisos selectivos referidos al DML sobre una tabla, debemos estructurar la cláusula de la siguiente forma: GRANT SELECT, UPDATE ON gamer.level_game TO ‘UANL@localhost’; Otorgar permisos selectivos De esta manera, definimos que un usuario pueda realizar determinadas acciones sobre una tabla. El usuario puede, por ejemplo sólo leer registros, agregar, o realizar todo tipo de operaciones menos eliminar. Tengamos presente para esto, pensar bien la relación operativa entre las diferentes acciones, previo a establecer las mismas. Otorgar permisos sobre columnas Otorgar permisos sobre columnas También podemos ir con más profundidad, estableciendo ciertos permisos sobre determinadas columnas de una tabla. Por ejemplo así podemos permitir que un usuario modifique solamente ciertos campos y evitar cambios sobre otros claves, como ser un documento de identidad o importes monetarios, entre otros Otorgar permisos sobre columnas Para esto, debemos definir cada campo específico separado por una coma, tal como hacemos una consulta del tipo SELECT, definiendo qué campos visualizar. GRANT UPDATE, SELECT (description) ON gamer.level_game TO ‘UANL@localhost’; Verificar permisos establecidos Permisos establecidos Ejecutando nuevamente el comando SHOW GRANTS para el usuario en cuestión, podremos ver los diferentes permisos que le han sido otorgados al mismo. Permisos establecidos También, accediendo a las propiedades de la tabla mediante TABLE INSPECTOR, podremos ver un detalle de los permisos por usuario establecidos. Sentencia revoke: quitar permisos Sentencia revoke Tal como existe una sentencia para otorgar diferentes permisos a un usuario de base de datos, también existe la sentencia que le quita dichos permisos. Se llama REVOKE. y funciona de igual forma a GRANT, pero a la inversa. Observemos ejemplos a continuación… Quitar todos los permisos Para quitarle todos los permisos a un usuario, sobre todos los objetos de todos los dominios, utilizamos la sentencia REVOKE ALL. REVOKE ALL ON *.* FROM ‘UANL@localhost’; El uso de *.* refiere a objetos.dominio Quitar un permiso determinado Para quitarle un permiso específico a un usuario, por ejemplo actualizar registros, sobre todos los objetos de todos los dominios, realizamos lo siguiente. REVOKE UPDATE ON *.* FROM ‘UANL@localhost’; Ejemplo en vivo Implementaremos las sentencias GRANT y REVOKE. Crear usuario y permisos sobre una DB Practicaremos la implementación del sublenguaje DCL. Duración: 15 minutos ACTIVIDAD EN CLASE Crear usuario y permisos sobre una DB Utilizaremos la base de datos GAMERS para crear un nuevo usuario y le estableceremos determinados permisos. ✔ Crea un usuario llamado UANL y asígnale lo mismo como contraseña. ✔ Abre una nueva ventana de conexión e inicia sesión con este usuario. ✔ Establece permisos de solo lectura de datos sobre la tabla GAME. ✔ Modifica un registro cualquiera de la tabla GAME y aplica los cambios. ✔ Establece permisos de lectura e inserción sobre la tabla CLASS. ✔ Agrega un registro en la tabla CLASS. ✔ Elimina este último registro agregado. ☕ Break ¡10 minutos y volvemos! Objetivos de la clase Reconocer e implementar las sentencias del sublenguaje TCL. Identificar en qué situación usar cada sentencia. MAPA DE CONCEPTOS Cómo implementarlo Fundamentos de TCL Transaction Control Language Cuándo implementarlo Commit Comandos Rollback Savepoint Sublenguaje TCL Fundamentos de TCL Fundamentos de TCL Se conoce como Transaction Control Language (o TCL) al grupo de sentencias del sub-lenguaje de Control de Transacciones que se utilizan para administrar transacciones en la DB. Se utilizan para gestionar los cambios realizados por las sentencias DML y agruparlas en transacciones lógicas. Fundamentos de TCL El papel de TCL es fundamental ya que, a través del mismo, controlamos las cláusulas u operaciones DML, agrupandolas de manera tal que se establezca una lógica transaccional cuando realizamos múltiples operaciones que afectan a una o más tablas. Básicamente nos ayuda a mantener la integridad de los datos manipulados. Fundamentos de TCL Cuando mencionamos operaciones DML, nos estamos refiriendo a los tres tipos de operaciones más importantes para la manipulación de datos: DML INSERT UPDATE DELETE Comandos de TCL para el control de transacciones Comandos TCL Transaction Control Language incluye tres sentencias claves que se integran a las cláusulas SQL, para poder controlar cada una de las operaciones del DML durante el proceso de ejecución de las mismas. Estos comandos son: TCL COMMIT ROLLBACK SAVEPOINT Comando Commit COMMIT es un comando que sirve para “confirmar” las operaciones realizadas sobre una o más tablas. Cuando es ejecutado, se ocupa de confirmar o guardar los cambios realizados en la o las tabla(s), haciéndolos permanentes y poniendo esos cambios a disposición del resto de los usuarios. Comando Commit Durante la ejecución de algunas de las sentencias DML, la o las modificaciones realizadas se guardan de forma “temporal” en un archivo especial del Servidor de la BD denominado log de transacciones. Al ejecutarse el comando COMMIT, dichas modificaciones impactan de forma permanente en la DB, reflejando los cambios en la tabla o tablas en cuestión. Comando Rollback ROLLBACK se ocupa de “deshacer”, o volver al estado permanente anterior a él o los cambios realizado(s) sobre la(s) tabla(s) en cuestión. Básicamente funciona como el comando UNDO (Deshacer), o CTRL+Z, que utilizamos de manera frecuente en cualquier programa de computadora. PARA RECORDAR Previo a utilizar Rollback debemos tener presente que, el mismo, solo funciona si no se ejecutó antes el comando COMMIT. En el caso de realizar una operación DML y luego haber ejecutado el comando COMMIT, la operación ya habrá impactado en la DB y no podrá deshacerse con ROLLBACK. Comando Savepoint SAVEPOINT nos permite establecer un punto de recuperación dentro de la transacción, utilizando un identificador. Podemos hacer un ROLLBACK deshaciendo sólo las instrucciones que se han ejecutado hasta un determinado SAVEPOINT que se indique. Comando Savepoint Ideal para implementarlo en modificaciones masivas de registros, estableciendo una marca específica cada cierto Sesión de registros modificados. Si en algún punto de la modificación debemos ejecutar ROLLBACK, podemos hacerlo definiendo alguno de los SAVEPOINT, para no tener que perder todo el Sesión de registros modificados. PARA RECORDAR Ten presente también que, al ejecutar el COMMIT, todo SAVEPOINT que hayamos establecido se perderá dado que en este punto, ROLLBACK no puede volver a ejecutarse. Definir el inicio de una transacción PARA RECORDAR Límites de una transacción Los límites de una transacción representan el ámbito de espacio temporal para cualquier tipo de modificación que se realice sobre la DB cual puede involucrar numerosas sentencias de DML. Para iniciar una transacción primeramente se debe escribir el comando START TRANSACTION, y luego se escriben aquellas sentencias de DML que se requiera modificar la DB. PARA RECORDAR Límites de una transacción Por defecto MySQL se ejecuta en modo autocommit, esto significa que si una sentencia de DML no está dentro de una transacción, cada una de ellas es atómica, como si estuviera entre un START TRANSACTION y un COMMIT. Paso 1 Inicio de una transacción Antes de ingresar en las prácticas con código SQL, veamos cómo Mysql Workbench ayuda a entender las transacciones, a través de sus herramientas gráficas, para manipular operaciones DML. Paso 2 Inicio de una transacción Ejecuta una consulta sobre alguna tabla. Verás que, al cargar la misma, existe un apartado para agregar, editar, o eliminar registros. Pulsa, ahora, alguno de estos botones y realiza en la tabla, la operación con el registro que has elegido. Paso 3 Inicio de una transacción Los botones de edición funcionan como inicio de una transacción: puedes eliminar uno o más registros, agregar, o modificar uno existente pero, si no pulsas el botón Apply, los cambios no se harán efectivos. Por lo tanto, Apply funciona como COMMIT, y Revert como ROLLBACK. Autocommit Autocommit Para definir el autocommit, MySQL cuenta con la variable llamada autocommit, seteada por defecto en 1 para que cada operación DML impacte automáticamente en la tabla. Para comenzar a trabajar con transacciones debemos desactivar previamente esta variable. Escribamos en una ventana de script, lo siguiente: SELECT @@AUTOCOMMIT; Autocommit Si su valor es 1 debemos pasarlo a 0, ejecutando el siguiente comando en la pestaña de script: SET @@AUTOCOMMIT = 0; También podemos verificar en el menú Query > Auto-Commit Transactions que no tenga el check. De tenerlo, haz clic sobre el punto de menú para desactivarlo. Start transaction Start transaction Llevemos a ejemplos con código a cada comando relacionado a transacciones que vimos en la primera parte de esta clase. Comenzamos por el principal: START TRANSACTION. Observemos cómo entra en acción este comando y cómo se comporta al momento de ejecutar operaciones DML. Start transaction Ejecutando una sentencia UPDATE, iniciando previamente la sentencia START TRANSACTION, veremos que el registro afectado se modificará sin problema alguno. START TRANSACTION; UPDATE class SET description = 'TRACKPAD BT' WHERE id_level = 10 AND id_class = 1; SELECT * FROM class; Start transaction Si sales de la sesión Mysql Workbench y vuelves a ingresar, verás que el cambio solicitado al registro de la tabla en cuestión, no se asentó. Faltó finalizar el inicio de la transacción con Commit para reflejar dicho cambio. Rollback transaction Rollback transaction Ejecutemos a continuación una consulta de eliminación de un registro. Iniciamos nuevamente la transacción, luego la operación DML y finalmente la consulta SELECT para visualizar el resultado. START TRANSACTION; DELETE FROM user_type WHERE id_user_type = 2; SELECT * FROM user_type order by id_user_type limit 10; Rollback transaction A través de la consulta SELECT, veremos que los registros son eliminados correctamente de la tabla. Ahora, en una nueva línea de la ventana de script, ejecutamos la sentencia rollback: ROLLBACK; Rollback transaction El registro que eliminamos anteriormente, volverá a su estado original. Así es como funciona la combinación de START TRANSACTION y ROLLBACK. Commit transaction Start transaction Ejecutando una sentencia UPDATE e iniciando previamente la sentencia START TRANSACTION, veremos que el registro afectado se modificará sin problema alguno. START TRANSACTION; UPDATE class SET description= '2D Digital Animation' WHERE id_level = 7 AND id_class = 145; SELECT * FROM class order by description limit 10; Commit transaction Vamos con una nueva operación del tipo DML. En este caso, ejecutamos una inserción y luego, visualizamos los resultados con SELECT. START TRANSACTION; INSERT INTO class (id_level, id_class, description) VALUES (15, 99, 'Test class'); SELECT * FROM class order by description DESC limit 10; Start transaction Llevemos a ejemplos con código a cada comando relacionado a transacciones que vimos en la primera parte de esta clase. Comenzamos por el principal: START TRANSACTION. Observemos cómo entra en acción este comando y cómo se comporta al momento de ejecutar operaciones DML. Commit transaction Avancemos con una nueva operación del tipo DML. Al igual que con los pasos anteriores, esta se hace efectiva apenas realizada. Commit transaction Igualmente, para confirmar de manera definitiva, debemos ejecutar el comando commit: COMMIT; Savepoint Savepoint Veamos a continuación cómo SAVEPOINT nos ayuda a controlar una modificación masiva de registros, pudiendo confirmar o deshacer por lotes, según consideremos, acorde a la lógica operativa. Ten presente que, toda instrucción asociada a este comando, es ejecutable solo en bases de datos innoDB. Savepoint El comando SAVEPOINT requiere establecer un identificador cada cierto punto para definir la posición del lote de registros insertados. El criterio del nombre de cada savepoint lo definimos nosotros. START TRANSACTION; INSERT INTO CLASS (id_level, id_class, description) VALUES (1, 1000,'class 1000'); INSERT INTO CLASS (id_level, id_class, description) VALUES (2, 1000,'class 1000'); INSERT INTO CLASS (id_level, id_class, description) VALUES (3, 1000,'class 1000'); INSERT INTO CLASS (id_level, id_class, description) VALUES (4, 1000,'class 1000'); INSERT INTO CLASS (id_level, id_class, description) VALUES (5, 1000,'class 1000'); INSERT INTO CLASS (id_level, id_class, description) VALUES (6, 1000,'class 1000'); INSERT INTO CLASS (id_level, id_class, description) VALUES (7, 1000,'class 1000'); INSERT INTO CLASS (id_level, id_class, description) VALUES (8, 1000,'class 1000'); savepoint lote_1; INSERT INTO CLASS (id_level, id_class, description) VALUES (1, 1002,'class 1000'); INSERT INTO CLASS (id_level, id_class, description) VALUES (2, 1002,'class 1000'); INSERT INTO CLASS (id_level, id_class, description) VALUES (3, 1002,'class 1000'); INSERT INTO CLASS (id_level, id_class, description) VALUES (4, 1002,'class 1000'); INSERT INTO CLASS (id_level, id_class, description) VALUES (5, 1002,'class 1000'); INSERT INTO CLASS (id_level, id_class, description) VALUES (6, 1002,'class 1000'); INSERT INTO CLASS (id_level, id_class, description) VALUES (7, 1002,'class 1000'); INSERT INTO CLASS (id_level, id_class, description) VALUES (8, 1002,'class 1000'); savepoint lote_2; Savepoint Podemos ver como SAVEPOINT impactó correctamente cada uno de los registros insertados en el conjunto de operación de DML. Savepoint Y, en la pestaña Action Output, encontraremos los dos bookmarks generados mediante SAVEPOINT. Rollback to Savepoint Rollback to Savepoint A través del comando ROLLBACK TO SAVEPOINT, podemos retroceder o “deshacer” el lote de comandos ejecutados hasta ese momento, de forma rápida y práctica Su sentencia es: ROLLBACK TO <savepoint>; Savepoint Si ejecutamos ROLLBACK TO lote_1 desharemos los registros 11 al 20 insertados , El criterio del nombre de cada savepoint lo definimos nosotros. Release Savepoint Release to Savepoint También, en el caso que lo consideremos necesario, podemos eliminar un SAVEPOINT ejecutando la sentencia: RELEASE SAVEPOINT <savepoint>; PARA RECORDAR Implementación de transacciones La implementación de un control de transacciones, tanto para confirmar como para deshacer las mismas, es muy utilizado principalmente dentro de Stored Procedures. Combinando el mismo con el uso de variables, y la ejecución de varias sentencias DML que dependen unas de otras, el control de transacciones nos ayudará a mantener consistente cada una de las tablas de la base de datos. Sentencias del sublenguaje TCL Presentaremos en formato .sql, el script de la implementación de dichas sentencias. Tarea Sentencias del sublenguaje TCL Consigna ✓ Elige dos tablas de las presentadas en tu proyecto. Realizarás una serie de modificaciones en los registros, controladas por transacciones. Formato ✓ Será, como siempre, un archivo del tipo .sql. ✓ Video explicativo Tarea Sentencias del sublenguaje TCL Aspectos a incluir ✓ En la primera tabla, si tiene registros, ✓ ✓ deberás eliminar algunos de ellos iniciando previamente una transacción. Si no tiene registros la tabla, reemplaza eliminación por inserción. Deja en una línea siguiente, comentada la sentencia Rollback, y en una línea posterior, la sentencia Commit. Si eliminas registros importantes, deja comentadas las sentencias para reinsertarlos. ✓ En la segunda tabla, inserta ocho ✓ ✓ nuevos registros iniciando también una transacción. Agrega un savepoint a posteriori de la inserción del registro #4 y otro savepoint a posteriori del registro #8 Agrega en una línea comentada la sentencia de eliminación del savepoint de los primeros 4 registros insertados. ¿Quieres saber más? Te dejamos material ampliado de la clase MATERIAL AMPLIADO Recursos multimedia ✓ Transacciones | Blog de José Juan Sánchez ✓ Savepoint y sentencias asociadas | Blog de José Juan Sánchez ¿Preguntas? Muchas gracias. Resumen de la clase hoy ✓ Creación de Usuarios ✓ Asignación de Permisos totales y parciales ✓ Eliminación de Permisos totales y parciales ✓ Transacciones ✓ Start Transaction ✓ Commit y Rollback ✓ Savepoint ✓ Release y Rollback to savepoint