MySQL 5.0以后引入了视图。视图实际是一个自身不存储数据的虚拟数据表。实际这个虚拟表的数据来自于访问视图的 SQL 查询的结果。MySQL 处理视图和处理数据表差不多,通过这种方式来满足很多需求。视图和数据表在 MySQL 中共享命名空间,然而 ,MySQL 处理而二者的方式并不相同,例如,视图没有触发器,并且无法使用 DROP TABLE 移除视图。
下面以 world 样例数据库为例来展示视图的工作机制。
CREATE VIEW Oceania AS
SELECT * FROM Country WHERE Continent = 'Oceania'
WITH CHECK OPTION;
SELECT Code, Name FROM Oceania WHERE Name = 'Australia';
下面是服务端执行上面语句可能的形式(临时表名称是随意取的,实际内部不知道是什么):
CREATE TEMPORARY TABLE TMP_Oceania_123 AS
SELECT * FROM Country WHERE Continent = 'Oceania';
SELECT Code, Name FROM TMP_Oceania_123 WHERE NAME = 'Australia';
这种形式显然存在性能问题,最好的方式是将视图和查询的分布查询改为一句 SQL 语句,如下所示:
SELECT Code, Name FROM Country
WHERE Continent = 'Oceania' AND Name = 'Australia';
在 MySQL 中会使用两种算法,称之为 MERGE 和 TEMTABLE,而且会尽可能地使用 MERGE 算法。甚至,MySQL 能够将嵌套视图进行合并。下图是两种算法的区别:
当视图中有 GROUP BY,DISTINCT,聚集函数,UNION,子查询或其他数据表之间不是一对一的关系时,MySQL 会使用 TEMPTABLE算法。如果想知道视图是使用 MERGE 还是 TEMPTABLE,可以使用 EXPLAIN 指令检查: