本文参考了高性能MySQL
数据库中的视图是虚拟表。 与实际表一样,视图包含一系列命名的行和列数据。 行和列数据是在定义视图查询引用的表以及引用视图时动态生成的。
视图的实现
视图不包含任何数据,使用SQL语句访问视图时,返回的数据由MySQL从其它表中生成。 视图和表位于同一个命名空间中,很多地方对视图和表的处理方式都相同。 但是,不能在视图中创建触发器,也不能使用DROP TABLE命令删除视图。
假设您创建了一个视图:
create view Oceania as
select * fromcountrywherecontinent=' Oceania '
with check选项;
实现视图的最简单方法是将select语句的结果存储在临时表中。 如果需要访问视图,则直接访问临时表即可。 例如:
select Code,namefromoceaniawherename=‘Australia’;
可以通过两种方法实现上述查询:使用临时表,或重写包含视图的查询,并将视图定义SQL直接包括在查询的SQL中。
使用临时表算法:
createtemporarytabletmp _ Oceania _ 123 as
select * fromcountrywherecontinent=‘Oceania’;
select Code,name from tmp _ Oceania _ 123 where name=‘Australia’;
使用合并算法:
select Code,Name from Country
where continent=‘Oceania’andname=‘Australia’;
如果可能的话,尽可能使用合并算法。 下图详细说明了这两种算法的实现。
如果视图包含Group by、Distinct、任何聚合函数、union、子查询等,则在无法在原始表记录和视图记录上建立一对一映射的场景中,MySQL将使用临时表算法可以使用Explain来确定要在MySQL中使用的具体算法。
更新视图
可以更新视图。 指定适当的条件后,可以更新、删除或向视图写入数据。 如果视图定义包含group by、union、聚合函数或其他特殊情况,则无法更新。 更新视图的查询可以是相关语句,但有一个限制,即更新的列必须来自同一个表。 无法更新使用临时表算法实现的视图。
视图的性能
使用临时表算法实现的视图可能会降低性能。 可能比直接使用等效查询语句要好一点。 MySQL递归执行这些视图,首先执行外部查询。 即使对外部查询优化程序进行了优化,也无法很好地进行内部和外部组合的优化。 使用视图提高性能需要更详细的测试。 通过集成算法实现的视图也有额外的开销,zjdxl的性能很难预测。
视图的限制
视图有很多限制。 例如,MySQL不支持物化视图。 将视图的结果数据存储在可显示的表中,并定期用数据填充原始表以刷新此表中的数据。 也不支持在视图中建立索引。 当然,可以通过构建缓存表或汇总表来模拟。 也可以直接使用工具Flexviews来实现这个目的。
因为MySQL不保存视图定义的原始SQL语句,所以如果要轻松修改和重新定义视图结果,可能会有人直接使用show create view语句查看前面的定义,但该语句查询的视图创建语句会令人失望。 没有格式、注释、缩进,几乎看不懂。