Rodrigo González MySQL Views MySQL Views Documentación de referencia: MySQL 5.6 Reference Manual - 18.5 Using Views MySQL 5.0 Manual en español - Capítulo 21 Vistas Introducción Las queries de tipo SELECT pueden llegar a ser bastante complejas, especialmente si hacemos consultas que utilizan joins y funciones. Por esta razón, podría ser conveniente pensar en algún método para guardar algunas queries complicadas que tengamos que utilizar frecuentemente, de manera que no tengamos que reescribirlas cada vez. Una forma de hacerlo podría ser codificando dichas sentencias (queries) en un script. Otra opción son las denominadas views (vistas). A diferencia de los scripts, que se guardan en archivos de texto, las vistas se guardan en la propia base de datos. Así, las vistas pueden ser utilizadas desde cualquier cliente de MySQL o desde cualquier aplicación que acceda a la base de datos (por ejemplo, a través de una API de MySQL para PHP). Más adelante Veremos las ventajas que puede suponer la utilización de vistas en lugar de usar directamente las tablas. Una vista es una query SELECT que se almacena en la base de datos como si fuera un objeto de la propia base de datos (las tablas y los usuarios, por ejemplo, son también objetos de la base de datos). Para crear una vista, se utiliza la sentencia CREATE VIEW como en el siguiente ejemplo: CREATE VIEW alumnos_min AS SELECT alumno_nombre, alumno_nif, alumno_curso_id FROM alumnos La sentencia anterior crea una vista llamada alumnos_min formada por las columnas alumno_nombre, alumno_nif y alumno_curso de la tabla alumnos. Puedes considerar que una vista es una tabla virtual formada solamente por las filas y columnas especificadas en la sentencia CREATE VIEW. La tabla (o tablas) mencionadas en la cláusula FROM se denominan tablas base para esa vista. Es decir, en el ejemplo anterior, alumnos sería la tabla base para la vista alumnos_min. Decimos que una vista es una tabla virtual porque en realidad, la vista en sí no almacena ninguna información, sino que hace referencia a los datos que están almacenados en su tabla base. 1 Rodrigo González MySQL Views Para extraer información de una vista, necesitamos referirnos a ella mediante alguna sentencia SQL. Siguiendo con el ejemplo anterior, vamos a utilizar una sentencia de tipo SELECT que en su cláusula FROM, en lugar de referenciar a una tabla, referencia a la vista alumnos_min: SELECT * FROM alumnos_min WHERE alumno_curso_id = 'ASIR' ORDER BY alumno_nombre La query SELECT del ejemplo anterior obtiene los resultados (result set) a partir de la tabla virtual representada por la vista alumnos_min. Cuando una vista ha sido creada mediante CREATE VIEW como acabamos de ver, decimos que se trata de una vista actualizable (updatable). Es decir, podremos utilizar esa vista en queries de tipo INSERT, UPDATE o DELETE. Veamos, por ejemplo, cómo podríamos realizar un UPDATE partiendo de la vista alumnos_min para actualizar la columna alumno_nif en la tabla alumnos (tabla base) para un alumno determinado: UPDATE alumnos_min SET alumno_nif = ‘13567882X’ WHERE alumno_nombre = ‘Eulogio’ Para eliminar una vista, utilizaremos la sentencia DROP VIEW: DROP VIEW alumnos_min Como las vistas al fin y al cabo son objetos de la base de datos, podrán utilizarlas aquellos usuarios de MySQL que tengan los privilegios adecuados. Ventajas del uso de vistas ● Independencia en el diseño: Las vistas limitan la exposición de las tablas a usuarios y/o aplicaciones externas. En definitiva, si el diseño de las tablas cambia, podemos modificar acordemente la vista de manera que los usarios/aplicaciones que utilizan dicha vista (que la consultan mediante queries) no necesitan estar al corriente de las modificaciones. Es decir, podría introducir cambios en el diseño de las tablas de la base de datos sin necesidad de modificar el códifo fuente de una aplicación que accede a la información de la base de datos a través de una vista. ● Seguridad de datos: Las vistas sirven para restringir el acceso a los datos de la(s) tabla(s) base, permitiendo sólo el acceso a las columnas indicadas en la cláusula AS SELECT o limitando el acceso a una fila o serie de filas especificadas mediante la cláusula WHERE. 2 Rodrigo González MySQL Views ● Simplificación de las queries: Las vistas pueden utilizarse para evitar la complejidad de algunas operaciones de selección de datos (por ejemplo, consultas de tipo SELECT complejas que incluyen JOINs, llamadas a funciones, etc.). ● Actualizabilidad (updatability): Las vistas pueden utilizarse para actualizar, insertar o borrar información de la tabla base. Creación de vistas A la hora de crear una vista, se puede utilizar cualquier elemento propio de la sintaxis de una SELECT. Es decir, se pueden crear vistas a partir de JOINs de distintas tablas, utilizar funciones, etc. ● Sintaxis de la sentencia CREATE VIEW CREATE [OR REPLACE] VIEW view_name [(column_alias_1[, column_alias_2]...] AS select_statement [WITH [CHECK OPTION] [CONSTRAINT constraint_name]] ● Ejemplo de vista basada en una query compleja (por ejemplo, queremos obtener en una vista los nombres y teléfonos de los alumnos que tienen avisos en una tabla de notificaciones): CREATE VIEW tlf_avisar_alumnos AS SELECT alumno_nombre, alumno_tlf FROM alumnos WHERE alumno_nif IN (SELECT DISTINCT alumno_nif FROM notificaciones) ORDER BY alumno_nombre ● Ejemplo de vista que utiliza join (la vista alumnnos_curso incorpora columnas de la tabla base alumnos y de la tabla base cursos): CREATE OR REPLACE VIEW alumnos_curso AS SELECT alumno_nombre, alumno_nif, curso_horas FROM alumnos JOIN cursos ON alumnos.alumno_curso_id = cursos.curso_id ● Si se incluyen las palabras clave OR REPLACE, la sentencia CREATE VIEW reemplazará cualquier vista ya existente que tuviera el mismo nombre. 3 Rodrigo González ● MySQL Views Si se nombran las columnas de la vista (column_alias1,2,...) en la cláusula CREATE VIEW, estaremos obligados a dar un nombre a cada una de las columnas. En cambio, si simplemente nombramos las columnas en la cláusula SELECT, puedes mencionar sólo las columnas que quieras renombrar. Por ejemplo, estas dos sentencias CREATE VIEW serían equivalentes (observa las diferencia entre ambos tipos de sintaxis): CREATE OR REPLACE VIEW alumnos_faltas (alumno_nombre, alumno_nif, total_faltas) AS SELECT alumno_nombre, alumno_nif, faltas_1a_ev + faltas_2a_ev FROM alumnos WHERE faltas_1a_ev + faltas_2a_ev >= 11 CREATE OR REPLACE VIEW alumnos_faltas AS SELECT alumno_nombre, alumno_nif, faltas_1a_ev + faltas_2a_ev AS total_faltas FROM alumnos WHERE faltas_1a_ev + faltas_2a_ev >= 11 ● Puede crearse una vista a partir de otra vista en vez de a partir de una tabla base. En ese caso, estaríamos hablando de vistas anidadas. ● La cláusula WITH CHECK OPTION puede utilizarse en una vista actualizable para evitar inserciones o actualizaciones excepto en los registros en que la cláusula WHERE de la sentencia_select (select_statement en la sintaxis de CREATE VIEW mostrada al principio de este apartado) se evalúe como true. Veremos un ejemplo en el siguiente apartado, dedicado a las vistas actualizables. Por ejemplo, al crear la vista alumnos_min podríamos haber utilizado la cláusula WHERE para indicar que la vista se restringe a alumnos que pertenezcan al curso ‘ASIR’: CREATE VIEW alumnos_min AS SELECT alumno_nombre, alumno_nif, alumno_curso_id FROM alumnos WHERE alumno_curso_id = 'ASIR' WITH CHECK OPTION Veremos un ejemplo en el siguiente apartado, dedicado a las vistas actualizables. 4 Rodrigo González MySQL Views Crear vistas actualizables Una vez que hemos creado una vista (con CREATE VIEW), podemos referenciarla mediante una query de tipo SELECT. Adicionalmente podremos referenciar dicha vista en queries de tipo INSERT, UPDATE y DELETE para modificar los datos almacenados en la tabla base (recuerda que la información no se almacena en la vista, por eso decimos que es una tabla virtual). Para poder ser referenciada en una query, de tipo INSERT, UPDATE o DELETE, debemos asegurarnos primero de que la vista es actualizable (updatable), para lo cual debe de cumplir una serie de condiciones: http://dev.mysql.com/doc/refman/5.6/en/view-updatability.html Si una vista no es actualizable, se dice que es read-only. Por el momento sólo vamos a trabajar con vistas actualizables (updatable views). ● Ejemplo de sentencia UPDATE sobre la vista actualizable alumnos_faltas (creada en uno de los ejemplos anteriores): UPDATE alumnos_faltas SET alumno_nombre = ‘Pepito’ WHERE alumno_nif = ‘12345678U’ Query OK, 1 row affected (0.04 sec) Rows matched: 1 Changed: 1 Warnings: 0 ● Intento de UPDATE sobre un campo calculado de la vista actualizable alumno_faltas: UPDATE alumnos_faltas SET total_faltas = 0 WHERE alumno_nombre = ‘Pepito’ ERROR 1348 (HY000): Column 'total_faltas' is not updatable ● Ejemplo de INSERT de una fila de alumnos en la vista actualizable alumnos_min que fue creada con las cláusulas WHERE y CHECK OPTION. Sentencia de creación de la vista alumnos_min: CREATE VIEW alumnos_min AS SELECT alumno_nombre, alumno_nif, alumno_curso_id FROM alumnos WHERE alumno_curso_id = 'ASIR' WITH CHECK OPTION Al añadir la cláusula WITH CHECK OPTION durante la creación de la vista, estamos restringiendo su actualización (INSERT, UPDATE o DELETE sobre dicha vista) a registros de alumnos pertenecientes al curso ‘ASIR’. 5 Rodrigo González MySQL Views Sentencia INSERT de una fila en la vista alumnos_min: INSERT INTO alumnos_min VALUES ('Romualdo', '12346987A', 'ASIR'); Query OK, 1 row affected (0.04 sec) Intento de INSERT de una fila en la vista alumnos_min que no cumple las restricciones indicadas en la cláusula WHERE durante la creación de la vista: INSERT INTO alumnos_min VALUES ('Zacarías', '19646987H', 'SMR') ERROR 1369 (HY000): CHECK OPTION failed 'views_db.alumnos_min' Puedes comprobar tú mismo que si no se hubiese utilizado la cláusula CHECK OPTION durante la creación de la vista alumnos_min, la setentencia INSERT anterior se hubiese completado sin error y el nuevo registro se hubiera almacenado en la tabla base alumnos. Cómo comprobar las vistas existentes en una base de datos MySQL Tenemos varias formas de comprobarlo, nosotros vamos a considerar la que nos ofrece una información más completa sobre la vista. Para ello necesitaremos consultar la base de datos information_schema, la cual tiene una tabla denominada views. Realiza un describe de dicha tabla (information_schema.views) para ver qué columnas tiene: mysql> DESCRIBE information_schema.views; +----------------------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------------------+--------------+------+-----+---------+-------+ | TABLE_CATALOG | varchar(512) | NO | | | | | TABLE_SCHEMA | varchar(64) | NO | | | | | TABLE_NAME | varchar(64) | NO | | | | | VIEW_DEFINITION | longtext | NO | | NULL | | | CHECK_OPTION | varchar(8) | NO | | | | | IS_UPDATABLE | varchar(3) | NO | | | | | DEFINER | varchar(77) | NO | | | | | SECURITY_TYPE | varchar(7) | NO | | | | | CHARACTER_SET_CLIENT | varchar(32) | NO | | | | | COLLATION_CONNECTION | varchar(32) | NO | | | | +----------------------+--------------+------+-----+---------+-------+ 10 rows in set (0.01 sec) 6 Rodrigo González MySQL Views Podemos consultar las vistas de una determinada base de datos (db_name) mediante la siguiente consulta: SELECT * FROM information_schema.views WHERE TABLE_SCHEMA = 'db_name'; Observarás que mediante esta consulta obtienes toda la información sobre la vista: su nombre, las columnas que componen la vista, si es actualizable (updatable) o no, etc. Ten en cuenta que la columna TABLE_NAME hace referencia al nombre de la vista. 7