在 MySQL 数据库中,视图(View)是一个命名的虚表,它由一个 SQL 查询来定义,可以当做表使用。与持久表(permanent table)不同的是,视图中的数据没有实际的物理存储。也就是说视图中的数据并不在数据库中实际存在,行和列的数据来自定义视图的查询中使用的表,在使用视图时动态生成的。
视图只保存了查询的 SQL 逻辑,不保存查询结果。
视图的作用
视图在数据库中发挥着重要的作用。视图的主要用途之一是被用做一个抽象装置,特别是对于一些应用程序,程序本身不需要关心基表(base table)的结构,只需要按照视图定义来取数据或更新数据;因此,视图同时在一定程度上起到一个安全层的作用。
MySQL 数据库 DBA 的一个常用的命令是 SHOW TABLES,该命令会显示出当前数据库下所有的表。但因为视图是虚表,同样被作为表显示出来。若用户只想查看当前架构下的基表,可以通过 information_schema 架构下的 TABLES 表来查询,并搜索表类型为 BASE TABLE 的表。
要想查看视图的一些元数据(meta data),可以访问 information_schema 架构下的 VIEWS 表,该表给出了视图的详细信息,包括视图定义者(definer)、定义内容、是否是可更新视图、字符集等。
创建:create [or replace] view 视图名称 as select 语句 [with cascaded | local check option];
查询:
- 查看创建视图的语句:
show create view 视图名称;
- 查看视图数据:
select * from 视图名称...;
修改:
1 | create [or replace] view 视图名称 as select 语句 [with cascaded | local check option]; |
删除:drop view [if exist] 视图名称;
视图的检查选项
当时用 with check option
子句创建视图时,MySQL 会通过视图检查正在更改的每一行,以使其符合视图的定义。MySQL 允许基于一个视图创建另一个视图,还会依赖视图中的规则以保持一致性。MySQL 提供了两个选项确定检查范围:cascaded 和 local,默认值为 cascaded。
视图的更新
要使视图可更新,视图中的行与基础表中的行之间必须存在一对一的关系。
如果视图包含以下任何一项,该视图不可更新:
- 聚合函数或窗口函数:
sum()
,min()
,max()
,count()
; distinct
;group by
;having
;union
或union all
。
视图可以简化用户对数据的理解,以及简化操作。
通过视图,用户只能查询和修改他们所能见到的数据。
视图帮助用户屏蔽真实表结构变化带来的影响。
物化视图
Oracle 数据库支持物化视图——该视图不是基于基表的虚表,而是根据基表实际存在的实表,即物化视图的数据存储在非易失的存储设备上。物化视图可用于预先计算并保存多表的连接(JOIN)或聚集(GROUP BY)等耗时较多的 SQL 操作结果。这样,在执行复杂查询时,就可以避免进行这些时耗的操作,从而快速得到结果。物化视图的好处是对于一些复杂的统计类查询能直接给出结果。在 Microsoft SQL Server 数据库中,称这种视图为索引视图。
在 Oracle 数据库中,物化视图的创建方式包括以下两种:
BUILD IMMEDIATE
BUILD DEFERRED
BUILD IMMEDIATE
是默认的创建方式,在创建物化视图的时候就生成数据,而 BUILD DEFERRED
则在创建物化视图时不生成数据,以后根据需要再生成数据。
查询重写是指当对物化视图的基表进行查询时,数据库会自动判断能否通过查询物化视图来直接得到最终的结果,如果可以,则避免了聚集或连接等这类较为复杂的 SQL 操作,直接从已经计算好的物化视图中得到所需的数据。
物化视图的刷新是指当基表发生了 DML 操作后,物化视图何时采用哪种方式和基表进行同步。刷新模式有两种:
ON DEMAND
ON COMMIT
ON DEMAND
意味着物化视图在用户需要的时候进行刷新,ON COMMIT 意味着物化视图在对基表的 DML 操作提交的同时进行刷新。
而刷新的方法有四种:
FAST
COMPLETE
FORCE
NEVER
FAST 刷新采用增量刷新,只刷新自上次刷新以来进行的修改。COMPLETE 刷新是对整个物化视图进行完全的刷新。如果选择 FORCE 方式,则数据库在刷新时会去判断是否可以进行快速刷新,如果可以,则采用 FAST 方式,否则采用 COMPLETE 的方式。NEVER 是指物化视图不进行任何刷新。
MySQL 数据库本身并不支持物化视图,换句话说,MySQL 数据库中的视图总是虚拟的。但是用户可以通过一些机制来实现物化视图的功能。例如要创建一个 ON DEMAND 的物化视图还是比较简单的,用户只需定时把数据导入到另一张表。