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:可选项,表示更新视图时要保证在该视图的权限范围之内。
创建视图后,如果创建视图的查询只有一张表,那么视图拥有的索引就是查询表的索引,即查询时走的索引与原表一致;如果建立索引时的查询跟两张表有关,那么查询视图时就会出现你查寻要的索引是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;
-
执行插入语句
-
插入第一条数据,满足所有条件。
mysql> insert into v4 values(12,'jack'); Query OK, 1 row affected (0.00 sec) -
插入第二条数据,不满足v4,其他都满足
mysql> insert into v4 values(14,'jack'); Query OK, 1 row affected (0.00 sec)通过上面的示例,我们知道并没有对视图v4进行校验。
-
插入第三条数据,不满足v3
mysql> insert into v4 values(40,'jack'); ERROR 1369 (HY000): CHECK OPTION failed 'surpass.v4' -
插入第四条数据,满足v3,不满足v2。
mysql> insert into v4 values(10,'jack'); ERROR 1369 (HY000): CHECK OPTION failed 'surpass.v4'即使v2没有加语句
with cascaded check option,也照样进行条件的检查,这也是级联检查的含义。 -
插入第五条数据,满足v3、v2,不满足v1
mysql> insert into v4 values(20,'jack'); ERROR 1369 (HY000): CHECK OPTION failed 'surpass.v4'Tip级联检查条件,他会一直往上检查,直到关联到真实的表数据。
-
LOCAL
比如,v2视图是基于v1视图的,如果在v2视图创建的时候指定了检查选项为 local ,但是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 local check option; create view v4 as select id,name from v3 where id > 5 and id < 14; -
执行插入语句
-
插入第一条数据,满足所有条件
mysql> insert into v4 values(12,'jack'); Query OK, 1 row affected (0.00 sec) -
插入第二条数据,不满足v4,其他都满足
mysql> insert into v4 values(14,'jack'); Query OK, 1 row affected (0.00 sec) -
插入第三条数据,不满足v3
mysql> insert into v4 values(40,'jack'); ERROR 1369 (HY000): CHECK OPTION failed 'surpass.v4' -
插入第四条数据,满足v3,不满足v2。
mysql> insert into v4 values(10,'jack'); Query OK, 1 row affected (0.00 sec)Tip这里同
cascaded的区别展现出来了,对于他引用的视图,如果没有填写检查选项,那么这个视图就不会做检查选项。
-
CASCADED和LOCAL
通过上面的实验我们知道CASCADED它会对所有它引用的父辈、祖父辈视图做级联检查,这个实验主要验证如果他关联的视图链表中如果有一个出现local,那么他后面的视图还是否继续检查选项。
-
创建视图
create view v1 as select id,name from student where id < 15; create view v2 as select id,name from v1 where id >10 with local check option; create view v3 as select id,name from v2 where id <30; create view v4 as select id,name from v3 where id > 5 with cascaded check option; -
执行插入语句
通过上面的示例,我们很快能判断如果不满足视图v4或者v3,都会终止插入数据,所以我们这里主要验证v2和v1的条件。
-
插入第一条数据,不满足v2条件
mysql> insert into v4 values(8,'jack'); ERROR 1369 (HY000): CHECK OPTION failed 'surpass.v4' -
插入第二条数据,不满足v1,其他都满足
mysql> insert into v4 values(20,'jack'); ERROR 1369 (HY000): CHECK OPTION failed 'surpass.v4'
-
仍然报错,也就是说只要由cascaded染指,那么他上面的local将变成鸡肋,没有什么大用处了。
更新
要使视图可更新,视图中的行与基础表中的行之间必须存在一一对应的关系。如果视图包含以下任何一项,则试图不可更新:
- 聚合函数或者窗口函数(SUM() , MIN() , MAX() , COUNT()等 );
- DISTINCT;
- GROUP BY;
- HAVING;
- 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
创建不可更新类试图无法添加检查选项。
作用和缺点
作用
①简化了操作,增强可读性,把经常使用的数据定义为视图。
我们在使用查询时,在很多时候我们要使用聚合函数,同时还要 显示其它字段的信息,可能还会需要关联到其它表,这时写的语句可能会很长,如果这个动作频繁发生的话,我们可以创建视图,这以后,我们只需要select * from view就可以啦,这样很方便;
②安全性,用户只能查询和修改能看到的数据。
因为视图是虚拟的,物理上是不存在的,只是存储了数据的集合,我们可以将基表中重要的字段信息,可以不通过视图给用户,视图是动态的数据的集合,数据是随着基表的更新而更新,而且,数据库的权限设置是对于表的,无法对于某行某个数据单独进行权限设置,所以视图可以只给用户看该看到的东西。同时,用户对视图不可以随意的更改和删除,可以保证数据的安全性。
③逻辑上的独立性,方便维护,屏蔽了真实表的结构带来的影响。
视图可以使应用程序和数据库表在一定程度上独立。如果没有视图,应用一定是建立在表上的。有了视图之后,程序可以建立在视图之上,从而程序与数据库表被视图分割开来。
缺点
①性能差
数据库必须把视图查询转化成对基本表的查询,如果这个视图是由一个复杂的多表查询所定义,那么,即使是视图的一个简单查询,数据库也要把它变成一个复杂的结合体,需要花费一定的时间。
②修改限制
当用户试图修改视图的某些信息时,数据库必须把它转化为对基本表的某些信息的修改,对于简单的视图来说,这是很方便的,但是,对于比较复杂的试图,可能是不可修改的。