MySQL 8.4 Reference Manual  /  Stored Objects  /  Restrictions on Views

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 TABLEALTER TABLE语句来删除或修改用于视图定义的表。即使删除或修改操作无效化了视图,也不会出现警告。相反,在使用视图时将出现错误。可以使用CHECK TABLE语句来检查由于删除或修改操作而无效化的视图。

关于视图可更新性,总的目标是如果任何视图理论上可更新,它应该在实际上也可更新。许多理论上可更新的视图现在已经可更新,但是仍然存在一些限制。详细信息请参阅第27.5.3节,“可更新和可插入视图”

当前视图实现存在一个缺陷。如果用户拥有创建视图所需的基本权限(CREATE VIEWSELECT权限),那么该用户不能在该对象上调用SHOW CREATE VIEW语句,除非该用户还拥有SHOW VIEW权限。

该缺陷可能会导致使用mysqldump工具备份数据库时出现问题,这可能是由于权限不足。这个问题在Bug #22062中描述。

解决问题的方法是管理员手动将SHOW VIEW权限授予给授予CREATE VIEW权限的用户,因为MySQL在创建视图时不会隐式授予该权限。

视图没有索引,因此索引提示不适用。在选择视图时使用索引提示是不允许的。

SHOW CREATE VIEW使用AS alias_name子句显示视图定义。如果一个列是从表达式创建的,缺省别名是表达式文本,这可能会很长。CREATE VIEW语句中的列别名在CREATE VIEW语句中被检查,检查的长度为64个字符(不是256个字符的别名长度限制)。因此,使用SHOW CREATE VIEW创建的视图如果任何列别名超过64个字符将失败。这可能会在以下情况下导致问题:

  • 视图定义无法复制到新的副本,这些副本强制执行列长度限制。

  • 使用mysqldump创建的备份文件不能在强制执行列长度限制的服务器上加载。

解决这两个问题的方法是修改每个问题视图定义,以使用更短的列别名。然后,视图可以正确复制,并且可以在不引发错误的情况下被dump和重新加载。要修改定义,可以使用DROP VIEWCREATE VIEW语句,或者使用CREATE OR REPLACE VIEW语句。

解决在重新加载视图定义时出现的问题的方法是编辑备份文件,以修改其CREATE VIEW语句。然而,这不会更改原始视图定义,这可能会在后续dump操作中引发问题。