视图(View)是一种虚拟存在的表。视图中的数据并不在数据库中实际存在,我们所看得到的视图中的行和列的数据来自定义视图时所使用的表(这个表也叫作基表,也叫做基表),并且是在使用视图时动态生成的。
通俗的讲,视图只保存了查询的SQL逻辑,不保存查询结果。所以我们在创建视图的时候,主要的工作就落在创建这条SQL查询语句上。
视图是一张虚拟表,最终的数据是来源于AS后面的select语句,select语句当中我们需要去指定我们要从哪一张表当中来查询数据,视图中所关联的基表就是select语句当中所查询的表
CREATE [OR REPLACE] VIEW 视图名称[(列名列表)] AS SELECT语句 [ WITH [
CASCADED | LOCAL ] CHECK OPTION ]
如果我们要去替换某张视图的话可以加上OR REPLACE,只写"CREATE"的话是"创建视图",写成"CREATE OR REPLACE"的话是"创建或者替换视图";
[OR REPLACE]中括号中的 OR REPLACE关键字是可选的。如果当前数据库中已经存在指定名称的视图时,没有该关键字,将会提示错误信息;如果使用了 OR REPLACE关键字,则当前正在创建的视图会覆盖掉原来同名的视图。
当使用WITH CHECK OPTION子句创建视图时,MySQL会通过视图检查正在更改的每个行,例如 插入,更新,删除,以使其符合视图的定义。
MySQL允许基于另一个视图创建视图,它还会检查依赖视图中的规则以保持一致性。
为了确定检查的范围,mysql提供了两个选项: CASCADED 和 LOCAL,默认值为 CASCADED 。
级联。
比如,v2视图是基于v1视图的,如果在v2视图创建的时候指定了检查选项为 cascaded,但是v1视图创建时未指定检查选项。 则在执行检查时,不仅会检查v2,还会级联检查v2的关联视图v1。
本地。
比如,v2视图是基于v1视图的,如果在v2视图创建的时候指定了检查选项为 local ,但是v1视图创建时未指定检查选项。 则在执行检查时,只会检查v2,不会检查v2的关联视图v1
方式一:
CREATE [OR REPLACE] VIEW 视图名称[(列名列表)] AS SELECT语句 [ WITH
[ CASCADED | LOCAL ] CHECK OPTION ]
方式二:
ALTER VIEW 视图名称[(列名列表)] AS SELECT语句 [ WITH [ CASCADED | LOCAL ] CHECK OPTION ]
DROP VIEW [IF EXISTS] 视图名称 [,视图名称] ...
注意:表如何查,视图就如何查
SELECT * FROM 视图名称 ...... ;
SHOW CREATE VIEW 视图名称\G;
在MySQL中,show tables不仅可以用于查看当前数据库中存在哪些数据表,同时也可以查看到当前数据库中存在哪些视图
show tables
不过,仅仅使用show tables语句,在输出结果中,我们根本无法区分到底哪些才是视图哪些才是真实的数据表(当然,视图的命名我们可以统一约定以"v_“开头)。此时,我们需要使用命令show full tables,该命令可以列出额外的table_type列,如果对应输出行上该列的值为"VIEW”,则表示这是一个视图。
show full tables;
要使视图可更新,视图中的行与基础表中的行之间必须存在一对一的关系。如果视图包含以下任何一
项,则该视图不可更新:
A. 聚合函数或窗口函数(SUM()、 MIN()、 MAX()、 COUNT()等)
B. DISTINCT
C. GROUP BY
D. HAVING
E. UNION 或者 UNION ALL
CREATE TABLE student (
id int primary key auto_increment comment '主键',
name varchar(20), -- 姓名
no int -- 年龄
);
INSERT INTO student(id,NAME,no) VALUES (1,'黛绮丝',2000100100),(2,'谢逊',2000100102),(3,'马殷天正',2000100103),(4,'柳岩',2000100104);
在创建视图的过程中我们使用了聚合函数
select count(*) from student;
create view stu_v_count as select count(*) from student;
select * from stu_v_count;
在创建视图的过程中我们使用了聚合函数,上述的视图中,就只有一个单行单列的数据,视图中的行与基础表中的行之间不存在一对一的关系,如果我们对这个视图进行更新或插入的,将会报错
insert into stu_v_count values(10);
or replace在此可加不可加
create or replace view stu_v_1 as select id,name from student where id <= 10;-- 创建视图
show tables;
show full tables;
show create view stu_v_1\G;
select * from stu_v_1;
select * from stu_v_1 where id < 3;
即进行代替,OR REPLACE起作用
create or replace view stu_v_1 as select id,name,no from student where id <= 10;-- 修改视图的第一种方式
select * from stu_v_1;
修改视图的第二种方式
alter view stu_v_1 as select id,name from student where id <= 10;-- 修改视图的第二种方式
select * from stu_v_1;
student表全程都不变
drop view if exists stu_v_1;
student表全程都不变
上述我们演示了,视图应该如何创建、查询、修改、删除,那么我们能不能通过视图来插入、更新数据呢? 接下来,做一个测试。
执行下述的SQL,我们会发现,id为6和17的数据都是可以成功插入的。 但是我们执行查询,查询出来的数据,却没有id为17的记录。
因为我们在创建视图的时候,指定的条件为 id<=10, id为17的数据,是不符合条件的,所以没有查
询出来,但是这条数据确实是已经成功的插入到了基表中。
为了避免以上情况的发生,需要借助WITH CHECK OPTION
create or replace view stu_v_1 as select id,name from student where id <= 10;
select * from stu_v_1;
select * from student;
以下发现student表发生了变化,原因是视图不存储数据,所以插入的数据都存储到了真实的student表中,即插入到了基表当中
insert into stu_v_1 values(6,'Tom');
select * from student;
insert into stu_v_1 values(17,'Tom22');
select * from student;
select * from stu_v_1;
drop view if exists stu_v_1;
select * from student;
注:在该演示的场景下,CASCADED与LOCAL的效果是一样的,
即create or replace view stu_v_1 as select id,name from student where id <= 10 WITH CASCADED CHECK OPTION;
等效于
create or replace view stu_v_1 as select id,name from student where id <= 10 WITH LOCAL CHECK OPTION;
create or replace view stu_v_1 as select id,name from student where id <= 10 WITH CASCADED CHECK OPTION;
select * from stu_v_1;
select * from student;
insert into stu_v_1 values(6,'Tom');
select * from stu_v_1;
select * from student;
发现插入失败
insert into stu_v_1 values(17,'Tom22');
select * from stu_v_1;
select * from student;
drop view if exists stu_v_1;
select * from student;
delete from student where id=6;
select * from student;
select * from student;
create or replace view stu_v_1 as select id,name from student where id <= 20;
insert into stu_v_1 values(5,'Tom');
insert into stu_v_1 values(25,'Tom');
select * from stu_v_1;
select * from student;
操作紧接着”11.1演示v1视图”
create or replace view stu_v_2 as select id,name from stu_v_1 where id >= 10 WITH CASCADED CHECK OPTION;
select * from stu_v_2;
insert into stu_v_2 values(7,'Tom');--失败
insert into stu_v_2 values(26,'Tom');--失败
insert into stu_v_2 values(15,'Tom');
select * from stu_v_2;
select * from student;
操作紧接着”11.2演示v2视图”
create or replace view stu_v_3 as select id,name from stu_v_2 where id <=15 ;
select * from stu_v_3;
insert into stu_v_3 values(11,'Tom');
select * from stu_v_3;
select * from student;
17虽然没有插入进去,但是它是执行成功了的,原因是:在创建stu_v_3的时侯没有加检查选项,所以不会进行检查,紧接着去看v2 视图发现17是大于10的;还会继续向下往v1检查,发现满足小于等于等于20
insert into stu_v_3 values(17,'Tom');
select * from stu_v_3;
select * from student;
发现失败,原因:28是大于15的,由于v3后面没有加检查选项,所以不会去进行检查;但是v3视图是依赖于v2视图的,v2视图中加了WITH CASCADED CHECK OPTION,所以会去检查,28大于等于10;紧接着会去检查v1,由于v2依赖于v1,所以WITH CASCADED CHECK OPTION会传递到v1,即v1也会拥有WITH CASCADED CHECK OPTION,检查后28>20,不符合所以失败
drop table student;
drop view stu_v_2;
drop view stu_v_3;
drop view stu_v_4;
通过看概念即可看了解
create or replace view stu_v_3 as select id,name from stu_v_2 where id <=15 with local check option;select * from stu_v_3;
CREATE TABLE student (
id int primary key auto_increment comment '主键',
name varchar(20), -- 姓名
no int -- 年龄
);
INSERT INTO student(id,NAME,no) VALUES (1,'黛绮丝',2000100100),(2,'谢逊',2000100102),(3,'马殷天正',2000100103),(4,'柳岩',2000100104);
create or replace view stu_v_1 as select id,name from student where id <= 10;
select * from stu_v_1;
drop table student;
select * from stu_v_1;
1). 简单
视图不仅可以简化用户对数据的理解,也可以简化他们的操作。那些被经常使用的查询可以被定义为视图,从而使得用户不必为以后的操作每次指定全部的条件。
2). 安全
数据库可以授权,但不能授权到数据库特定行和特定的列上。通过视图用户只能查询和修改他们所能见到的数据
3). 数据独立
视图可帮助用户屏蔽真实表结构变化带来的影响。