El procesamiento de vistas no está optimizado:
No es posible crear un ínidice en una vista.
Los índices pueden utilizarse para procesar vistas usando un algoritmo de combinación (MERGE). Sin embargo, una vista que se procesa con el algoritmo de tablas temporales (temptable) no es capaz de tomar ventaja de los índices que hacen referencia a las tablas que contiene (aunque los índices pueden ser usados durante la generación de las tablas temporales).
Las subconsultas no pueden utilizarse en la cláusula FROM
de una vista. Esta limitación será removida en el futuro.
Existe un principio general por el que no se puede modificar una tabla y seleccionar de la misma en una subconsulta. Ver Sección H.3, “Restricciones en subconsultas”.
El mismo principio se aplica también si se hace una selección de una vista que hace una selección de una tabla, si la vista selecciona de la tabla dentro de una subconsulta, y la vista es evaluada usando el algoritmo de combinación (merge). Ejemplo:
CREATE VIEW v1 AS SELECT * FROM t2 WHERE EXISTS (SELECT 1 FROM t1 WHERE t1.a = t2.a); UPDATE t1, v2 SET t1.a = 1 WHERE t1.b = v2.b;
Si la vista se evalúa usando una tabla temporal, se
puede seleccionar de la tabla en la subconsulta
de la vista y modificarla en la consulta exterior.
En este caso la vista se almacenará en una tabla temporal y por ello no se está
realmente seleccionando de una tabla en una subconsulta y modificándola
“al mismo tiempo”. (Esta es otra razón por la que tal vez sea deseable
forzar a MySQL para que use el algoritmo de tablas (temptable) temporales especificando las
palabras
ALGORITHM = TEMPTABLE en la definición de la vista.)
Se puede usar DROP TABLE o ALTER
TABLE para eliminar o modificar una tabla utilizada en
la definición de una vista (lo cual invalida la vista) y no se obtendrá
ninguna alerta de las operaciones de elimiar o modificar.
Sin embargo, se obtiene un error más tarde, cuando se utiliza la vista.
Algunas sentencias “congelan” una definición de vista:
Si una sentencia preparada por PREPARE se refiere
a una vista, los contenidos de la vista que se ven cada vez que
se ejecuta la sentencia, serán los contenidos de la vista en el
momento en el que la sentencia fue preparada.
Esto es cierto incluso si la definición de la vista se
cambia después de preparar la sentencia y antes de que ésta se
ejecute. Ejemplo:
CREATE VIEW v AS SELECT 1; PREPARE s FROM 'SELECT * FROM v'; ALTER VIEW v AS SELECT 2; EXECUTE s;
El resultado devuelto por la sentencia EXECUTE
es 1, y no 2.
Si una sentencia en una rutina almacenada se refiere a una vista, los contenidos de la vista que ve la sentencia son sus contenidos de la primera ejecución de la sentencia. Esto significa por ejemplo que si se ejecuta una sentencia en un bucle, en todas las iteraciones de la sentencia se verá el mismo contenido de la vista, aunque la definición de la vista cambie durante el bucle. Ejemplo:
CREATE VIEW v AS SELECT 1;
delimiter //
CREATE PROCEDURE p ()
BEGIN
DECLARE i INT DEFAULT 0;
WHILE i < 5 DO
SELECT * FROM v;
SET i = i + 1;
ALTER VIEW v AS SELECT 2;
END WHILE;
END;
//
delimiter ;
CALL p();
Cuando se llama al procedimiento p(), el SELECT devuelve siempre 1 dentro del bucle, aunque dentro del mismo cambie la definición de la vista.
Con respecto a las actualizaciones en vistas, el objetivo
es que cualquier vista que sea teóricamente actualizable, tiene que
serlo en la práctica. Esto incluye vistas que tienen
UNION en su definición. Actualmente, no todas las vistas teóricamente
actualizables se pueden actualizar. La implementación inicial de vistas fue
deliberadamente escrita de esta forma para obtener en MySQL vistas utilizables y
actualizables lo antes posible. Muchas vistas teóricamente actualizables
pueden ser actualizadas actualmente, pero algunas limitaciones siguen existiendo:
Las vistas actualizables con subconsultas en cualquier lugar
que no sea en la cláusula WHERE.
Algunas vistas que tienen subconsultas en la
lista SELECT podrían ser actualizables.
No se puede utilizar UPDATE para actualizar más de una
tabla incluida en una vista que sea definida como un join.
No se puede usar una sentencia DELETE para actualizar
una vista que está definida como un JOIN.
Ésta es una traducción del manual de referencia de MySQL, que puede encontrarse en dev.mysql.com. El manual de referencia original de MySQL está escrito en inglés, y esta traducción no necesariamente está tan actualizada como la versión original. Para cualquier sugerencia sobre la traducción y para señalar errores de cualquier tipo, no dude en dirigirse a mysql-es@vespito.com.
