视图

视图:​​view​​,是一种有结构(有行有列),但没有结果(结构中不真实存放数据)的虚拟表,虚拟表的结构来源不是自己定义的,而是从对应的基表(视图的数据来源)中产生的。

创建视图

首先,给出创建视图的基本语法,

  • 基本语法:

​create view + 视图名 + as + select语句;​​其中,​​select​​语句可以是普通查询,也可以是连接查询、联合查询、子查询等。

此外,视图根据数据的来源,可以分为单表视图和多表视图:

  • 单表视图:基表只有一个;
  • 多表视图:基表至少两个。

执行如下 SQL 语句,进行测试:

-- 单表视图
create view my_v1 as select * from
create view my_v2 as select * from

-- 多表视图
create view my_v3 as
select * from student as s left join class c
on

史上最简单的 MySQL 教程(二十八)「视图」_视图数据增删查改语句

如上图所示,在我们创建多表视图的时候,由于表​​student​​和​​class​​中都含有​​id​​字段,因此导致出现错误“重复列名”。修改上述创建多表视图的 SQL 语句,继续进行测试:

-- 多表视图
create view my_v3 as
select s.*, c.grade, c.room from student as s left join class c
on

史上最简单的 MySQL 教程(二十八)「视图」_表视图_02

如上图所示,当我们去掉表​​class​​中的​​id​​字段之后,成功创建多表视图。这是因为,当视图的基表有多张的时候,字段名不能重复。

查询视图

在这里,查询视图是指查看视图的结构,而不是查看视图的结果。

由于视图是一张虚拟表,因此表的所用查询语句,都适用于视图,例如:

​desc + 视图名;​​​​show tables + 视图名;​​​​show create table + 视图名;​

执行如下 SQL 语句,进行测试:

-- 查询视图
desc my_v1;
show create table

史上最简单的 MySQL 教程(二十八)「视图」_视图数据增删查改语句_03

虽然视图是虚拟表,但它和真正的表,至少在关键字上还是有区别的,因此在查询视图创建语句的时候,可以使用如下 SQL 语句:

-- 查询视图创建语句
show create view

史上最简单的 MySQL 教程(二十八)「视图」_表视图_04

此外,视图一旦创建,系统就会在视图对应的数据库文件夹下创建一个对应的​​frm​​结构文件,以保证结构的完整性。

使用视图

在操作数据库表的过程中,使用视图,主要就是为了查询,因此将视图当做表一样查询即可。

在这里需要注意的是,虽然我们说视图是一个虚拟表,它不保存数据,但是它却可以获取数据。

执行如下 SQL 语句,进行测试:

-- 使用视图
select * from
select * from
select * from

史上最简单的 MySQL 教程(二十八)「视图」_表视图_05

如上图所示,我们查询视图的结果和查询创建视图时​​as​​后面连接的​​select​​语句的结果完全相同。因此,我们也可以认为:创建视图,就是给一条​​select​​语句起别名,或者说是封装​​select​​语句。

修改视图

视图本身不可修改,但是视图的来源(​​select​​)语句是可以修改的。因此,修改视图,就是修改视图的来源(​​select​​)语句。

  • 基本语法:

​alter view + 视图名 + as + 新的select语句;​

执行如下 SQL 语句,进行测试:

-- 修改视图
alter view my_v1 as
select id, name, gender, age, c_id from

史上最简单的 MySQL 教程(二十八)「视图」_视图算法和视图的意义_06

删除视图

与视图的其他操作相比,删除视图比较简单,

  • 基本语法:

​drop view + 视图名;​

执行如下 SQL 语句,进行测试:

-- 删除视图
drop table

-- 删除视图
drop view

史上最简单的 MySQL 教程(二十八)「视图」_表视图_07

如上图所示,我们不能用

​drop table + 视图名;​​来删除视图,因为​​table​​包含真实的数据,而​​view​​说到底就是封装的​​select​​语句,并不包含真实的数据。虽然删除视图并不会影响数据,但在实际工作中,建议还是不要乱删别人建立的视图,因为视图封装的​​select​​语句很有可能包含复杂的业务逻辑。

视图意义

  • 视图可以节省 SQL 语句,将一条复杂的查询语句用视图来进行封装,以后可以直接对视图进行操作;
  • 数据安全,视图操作主要是针对查询的,如果对视图结构进行处理,例如删除,并不会影响基表的数据;
  • 视图往往在大型项目中使用,而且是多系统使用,可以对外提供有用的数据,但是隐藏关键(或无用)的数据;
  • 视图是对外提供友好型的,不同的视图提供不同的数据,就如专门对外设计的一样;
  • 视图可以更好(或者说,容易)的进行权限控制。

温馨提示:符号​​[]​​括起来的内容,表示可选项;符号​​+​​,则表示连接的意思。


———— ☆☆☆ —— ​​返回 -> 史上最简单的 MySQL 教程 <- 目录​​ —— ☆☆☆ ————


视图数据操作

视图数据操作:虽然我们说视图可以称之为​​select​​语句的别名,但实际上,它和别名并不一样,因为视图是可以进行数据写操作的,只不过有很多限制而已。

新增数据

在这里,新增数据就是指通过视图直接对基表进行数据的新增操作。

  • 限制 1:多表视图不能进行新增数据。

执行如下 SQL 语句,进行测试:

-- 查询视图 my_v3 结构
desc my_v3;

-- 多表视图新增数据
insert into my_v3 values(7,'Gates','boy',2,170,'PM3.5','A315');

史上最简单的 MySQL 教程(二十八)「视图」_视图算法和视图的意义_08

  • 限制 2:可以向单表视图新增数据,但视图中包含的字段必须有基表中所有不能为空的字段。

执行如下 SQL 语句,进行测试:

-- 查询 student 表结构
desc student;

-- 创建视图 my_v4
create view my_v4 as
select id,name,age,c_id from

-- 单表视图新增数据
insert into my_v4 values(7,'Gates',25,2);

史上最简单的 MySQL 教程(二十八)「视图」_视图数据增删查改语句_09

如上图所示,在我们新建的视图​​my_v4​​中,没有包含不能为空的字段​​gender​​,因此在我们向​​my_v4​​中新增数据的时候,报错。其实,这也很好理解,试想,在 MySQL 尝试将视图中新增的数据(一条记录)插入到基表的时候,忽然发现一个本不能为​​null​​的字段的值为默认值​​null​​,自然就会报错啦!反之,如果单表视图中包含了基表中的全部非空字段,自然可以插入成功。执行如下 SQL 语句,进行测试:

-- 查询 class 表数据
select * from

-- 创建视图 my_v5
create view my_v5 as
select * from

-- 单表视图新增数据
insert into my_v5 values(2,'PM2016','A315');

-- 查询 class 表数据
select * from

史上最简单的 MySQL 教程(二十八)「视图」_视图算法和视图的意义_10

如上图所示,显然我们通过单表视图向基表中插入数据成功啦!

删除数据

与新增数据类似,

  • 多表视图不能删除数据;
  • 单表视图可以删除数据。

执行如下 SQL 语句,进行测试:

-- 查询多表视图 my_v3
select * from

-- 删除多表视图 my_v3 中记录
delete from my_v3 where id = 2;

-- 查询单表视图 my_v5
select * from

-- 删除单表视图 my_v5 中记录
delete from my_v5 where id = 2;

-- 查询单表视图 my_v5
select * from

史上最简单的 MySQL 教程(二十八)「视图」_视图数据增删查改语句_11

更新数据

理论上,无论多表视图还是单表视图,都可以进行数据的更新。

执行如下 SQL 语句,进行测试:

-- 查询单表视图 my_v5
select * from

-- 更新单表视图 my_v5
update my_v5 set grade = 'PM2014' where id = 5;

-- 查询单表视图 my_v5
select * from-- 查询单表视图 my_v5
select * from

-- 更新单表视图 my_v5
update my_v5 set grade = 'PM2014' where id = 5;

-- 查询单表视图 my_v5
select * from

史上最简单的 MySQL 教程(二十八)「视图」_视图数据增删查改语句_12

此外,更新视图数据并不总是成功的,这是因为有更新限制的存在。那么何为更新限制呢?

  • 更新限制:

​with check option​

  • ,如果创建视图的时候,设置了某个字段的限制,那么对视图进行更新操作的时候,系统就会进行验证,要保证更新之后,数据依然可以被查出来,否则不让更新。

执行如下 SQL 语句,进行测试:

-- 创建单表视图 my_v6
create view my_v6 as
select * from student where height > 170 with check option;

-- 查询单表视图 my_v6
select * from

-- 更新单表视图 my_v6
update my_v6 set height = 165 where id = 6;

史上最简单的 MySQL 教程(二十八)「视图」_表视图_13

如上图所示,在更新视图的时候,更新失败,这是因为其违反了我们设置的更新限制。那么,视图之外的数据,我们能不能修改呢?执行如下 SQL 语句,进行测试:

-- 查询单表视图 my_v6
select * from

-- 更新单表视图 my_v6
update my_v6 set height = 188 where id = 4;

-- 查询单表视图 my_v6
select * from

史上最简单的 MySQL 教程(二十八)「视图」_视图增删查改语句_14

如上图所示,更新视图​​my_v6​​之外数据的时候,显示成功。但是,待我们重新查询视图​​my_v6​​数据的时候,发现并没有真正更新成功。这是为什么呢?原因就在于我们不能通过视图去操作视图之外的数据。举一个不太恰当的例子,我们不能用自己手去操作别人兜里的钱啊!

视图算法

视图算法,即系统对视图以及外部查询视图的​​select​​语句的一种解析方式。视图算法有三种,分别为:​​undefined​

  • :未定义(默认的),这不是一种实际使用的算法,而是一个“推卸责任”的算法。在未定义的情况下,告诉系统,视图没有定义算法,请自己选择。

​temptable​

  • :临时表算法,系统先执行视图的

​select​

  • 语句,后执行外部查询语句。

​merge​

  • :合并算法,系统先将视图对应的

​select​

  • 语句与外部查询视图的

​select​

  • 语句进行合并,然后再执行。此算法比较高效,且在未定义算法的时候,经常会默认选择此算法。

对于视图的算法,我们需要在创建视图的时候指定,

  • 基本语法:

​create + [algorithm = temptable/merge/undefined] + view + 视图名 + as + select语句;​

执行如下 SQL 语句,进行测试:

-- 查看视图 my_v2 的默认算法
show create view

-- 指定视图 my_v7 算法为 temptable
create algorithm = temptable view my_v7 as
select * from

-- 查看视图 my_v7 的指定算法
show create view

史上最简单的 MySQL 教程(二十八)「视图」_视图增删查改语句_15

如上图所示,我们指定了视图​​my_v7​​的算法为​​temptable​​,但是对于算法的选择,我们该如何判断呢?答案是:如果视图的​​select​​语句中包含一个查询子句(五子句,包括​​where​​、​​group by​​、​​order by​​、​​having​​和​​limit​​),而且很有可能查询子句的顺序比外部的查询语句的顺序要靠后(五子句的顺序),那么一定要使用​​temptable​​算法,其他情况可以不用指定,默认即可。

至此,我们已经将视图的内容大致讲完了。有一点需要我们特别注意,那就是:视图最重要的功能就是查询,其他如增、删、改的操作一般不会使用,也不建议通过视图来操作基表的数据。


温馨提示:符号​​[]​​括起来的内容,表示可选项;符号​​+​​,则表示连接的意思。


———— ☆☆☆ —— ​​返回 -> 史上最简单的 MySQL 教程 <- 目录​​ —— ☆☆☆ ————