27.9 视图的限制
在定义视图时,最大可以引用61个表。
视图处理不被优化:
-
不能在视图上创建索引。
-
可以在使用 merge 算法处理的视图上使用索引。然而,使用 temptable 算法处理的视图不能利用其基础表的索引(虽然可以在生成临时表时使用索引)。
有一般原则:不能在同一个查询中修改和查询同一个表。请参阅第15.2.15.12节,“子查询限制”。
同样,如果视图从表中选择数据,并且视图在子查询中选择数据,并且视图使用 merge 算法评估,同样不能修改该表。例如:
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;
如果视图使用临时表,则可以在视图子查询中选择数据,并且在外部查询中修改该表。在这种情况下,视图被存储在临时表中,因此实际上并不是在子查询中选择数据并修改该表。 (这也是使用 temptable 算法强制 MySQL 使用 temptable 算法的原因之一。)
可以使用DROP TABLE
或ALTER TABLE
语句来删除或修改用于视图定义的表。即使删除或修改操作无效化了视图,也不会出现警告。相反,在使用视图时将出现错误。可以使用CHECK TABLE
语句来检查由于删除或修改操作而无效化的视图。
关于视图可更新性,总的目标是如果任何视图理论上可更新,它应该在实际上也可更新。许多理论上可更新的视图现在已经可更新,但是仍然存在一些限制。详细信息请参阅第27.5.3节,“可更新和可插入视图”。
当前视图实现存在一个缺陷。如果用户拥有创建视图所需的基本权限(CREATE VIEW
和SELECT
权限),那么该用户不能在该对象上调用SHOW CREATE VIEW
语句,除非该用户还拥有SHOW VIEW
权限。
该缺陷可能会导致使用mysqldump工具备份数据库时出现问题,这可能是由于权限不足。这个问题在Bug #22062中描述。
解决问题的方法是管理员手动将SHOW VIEW
权限授予给授予CREATE VIEW
权限的用户,因为MySQL在创建视图时不会隐式授予该权限。
视图没有索引,因此索引提示不适用。在选择视图时使用索引提示是不允许的。
SHOW CREATE VIEW
使用AS
子句显示视图定义。如果一个列是从表达式创建的,缺省别名是表达式文本,这可能会很长。CREATE VIEW语句中的列别名在alias_name
CREATE VIEW
语句中被检查,检查的长度为64个字符(不是256个字符的别名长度限制)。因此,使用SHOW CREATE VIEW
创建的视图如果任何列别名超过64个字符将失败。这可能会在以下情况下导致问题:
-
视图定义无法复制到新的副本,这些副本强制执行列长度限制。
-
使用mysqldump创建的备份文件不能在强制执行列长度限制的服务器上加载。
解决这两个问题的方法是修改每个问题视图定义,以使用更短的列别名。然后,视图可以正确复制,并且可以在不引发错误的情况下被dump和重新加载。要修改定义,可以使用DROP VIEW
和CREATE VIEW
语句,或者使用CREATE OR REPLACE VIEW
语句。
解决在重新加载视图定义时出现的问题的方法是编辑备份文件,以修改其CREATE VIEW
语句。然而,这不会更改原始视图定义,这可能会在后续dump操作中引发问题。