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.