View

🗞️ 返回专题页

视图

定义与基本语法

视图(view)是一种虚拟存在的表。视图中的数据并不在数据库中实际存在,行和列数据来自定义视图的查询中使用的表(被称为基表),并且是在使用视图时动态生成的。

通俗的说,视图只保存了查询的SQL逻辑,不保存查询结果。所以我们在创建视图的时候,主要的工作就落在创建这条SQL查询语句上。

关系型数据库中的数据是由一张一张的二维关系表所组成,简单的单表查询只需要遍历一个表,而复杂的多表查询需要将多个表连接起来进行查询任务。对于复杂的查询事件,每次查询都需要编写MySQL代码效率低下。为了解决这个问题,数据库提供了视图(view)功能。

MySQL在定义视图上没什么限制,基本上所有的查询都可定义为视图,同时也支持可更新视图(当然只有在视图和行列与基础表的行列之间存在一一对应关系时才能更新)。

//创建视图
CREATE [OR REPLACE] [ALGORITHM={UNDEFINED|MERGE|TEMPTABLE}]
VIEW VIEW_NAME[(属性清单)]
AS SELECT语句 [WITH[CASCADE|LOCAL] CHECK OPTION];
一般:创建或替代视图VIEW_NAME来源于SELECT语句
例子:create or replace algorithm=UNDEFINED
 view stu_v_1
 as select * from emp WITH  CHECK OPTION;

参数说明:
(1)ALGORITHM:可选项,表示视图选择的算法。
(2)VIEW_NAME:表示要创建的视图名称。
(3)属性清单:可选项,指定视图中各个属性的名词,默认情况下与SELECT语句中的查询的属性相同(一一对应)。
(4)SELECT语句:表示一个完整的查询语句,将查询记录导入视图中。
(5)WITH CHECK OPTION:可选项,表示更新视图时要保证在该视图的权限范围之内。

Note

创建视图后,如果创建视图的查询只有一张表,那么视图拥有的索引就是查询表的索引,即查询时走的索引与原表一致;如果建立索引时的查询跟两张表有关,那么查询视图时就会出现你查寻要的索引是b表的非主键索引,却发现实际查询用到的索引有b表的主键索引和你需要的索引,而且如果a与b表建立过约束索引的话,还会走约束索引,没有就会有a表的全表扫描**,所以创建视图要尽量避免多表查询。**

//查询视图(与正常查询表无差别)
查看创建视图语句:SHOW CREATE VIEW VIEW_NAME;
查看视图数据:SELECT * FROM VIEW_NAME.....;
索引与封装表的索引一致
//修改视图
第一种:create or replace view view_name[(属性清单)] as select语句 [with [cascade|local] check option];
第二种:alter view view_name[(属性清单)] as select语句 [with [cascade|local] check option];
//删除视图
drop view [IF EXISTS] view_name[,view_name]...;

检查选项

当使用WITH CHECK OPTION子句创建视图时,MySQL会通过视图检查正在更改的每个行,例如 插 入,更新,删除,以使其符合视图的定义。 MySQL允许基于另一个视图创建视图,它还会检查依赖视 图中的规则以保持一致性。为了确定检查的范围,mysql提供了两个选项: CASCADED 和 LOCAL ,默认值为 CASCADED 。

CASCADED

比如,v2视图是基于v1视图的,如果在v2视图创建的时候指定了检查选项为 cascaded,但是v1视图创建时未指定检查选项。 则在执行检查时,不仅会检查v2,还会级联检查v2的关联视图v1;接下来用案例分析。

create view v1 as select id,name from student where id < 15;
create view v2 as select id,name from v1 where id >10;
create view v3 as select id,name from v2 where id <30 with cascaded check option;
create view v4 as select id,name from v3 where id > 5 and id < 14;

LOCAL

比如,v2视图是基于v1视图的,如果在v2视图创建的时候指定了检查选项为 local ,但是v1视图创 建时未指定检查选项。 则在执行检查时,知会检查v2,不会检查v2的关联视图v1。

CASCADED和LOCAL

通过上面的实验我们知道CASCADED它会对所有它引用的父辈、祖父辈视图做级联检查,这个实验主要验证如果他关联的视图链表中如果有一个出现local,那么他后面的视图还是否继续检查选项。

Caution

仍然报错,也就是说只要由cascaded染指,那么他上面的local将变成鸡肋,没有什么大用处了。


更新

要使视图可更新,视图中的行与基础表中的行之间必须存在一一对应的关系。如果视图包含以下任何一项,则试图不可更新:

  1. 聚合函数或者窗口函数(SUM() , MIN() , MAX() , COUNT()等 );
  2. DISTINCT;
  3. GROUP BY;
  4. HAVING;
  5. UNION或者UNION ALL。
创建视图
mysql> create or replace view v1  as select count(*) from emp ;
Query OK, 0 rows affected (0.01 sec)
 
查看视图内容
mysql> select * from v1;
+----------+
| count(*) |
+----------+
|        6 |
+----------+
1 row in set (0.00 sec)

更新数据
mysql> insert into v1 values(10);
ERROR 1471 (HY000): The target table v1 of the INSERT is not insertable-into
Note

创建不可更新类试图无法添加检查选项。

作用和缺点

作用

简化了操作,增强可读性,把经常使用的数据定义为视图。

我们在使用查询时,在很多时候我们要使用聚合函数,同时还要 显示其它字段的信息,可能还会需要关联到其它表,这时写的语句可能会很长,如果这个动作频繁发生的话,我们可以创建视图,这以后,我们只需要select * from view就可以啦,这样很方便;

安全性,用户只能查询和修改能看到的数据。

因为视图是虚拟的,物理上是不存在的,只是存储了数据的集合,我们可以将基表中重要的字段信息,可以不通过视图给用户,视图是动态的数据的集合,数据是随着基表的更新而更新,而且,数据库的权限设置是对于表的,无法对于某行某个数据单独进行权限设置,所以视图可以只给用户看该看到的东西。同时,用户对视图不可以随意的更改和删除,可以保证数据的安全性。

逻辑上的独立性,方便维护,屏蔽了真实表的结构带来的影响。

视图可以使应用程序和数据库表在一定程度上独立。如果没有视图,应用一定是建立在表上的。有了视图之后,程序可以建立在视图之上,从而程序与数据库表被视图分割开来。

缺点

性能差

数据库必须把视图查询转化成对基本表的查询,如果这个视图是由一个复杂的多表查询所定义,那么,即使是视图的一个简单查询,数据库也要把它变成一个复杂的结合体,需要花费一定的时间。

修改限制

当用户试图修改视图的某些信息时,数据库必须把它转化为对基本表的某些信息的修改,对于简单的视图来说,这是很方便的,但是,对于比较复杂的试图,可能是不可修改的。