MySQL的视图(二十二)

勿以恶小而为之,勿以善小而不为--------------------------刘备

上一章简单介绍了 MySQL合并查询结果(二十一),如果没有看过,请观看上一章

一 . 视图

一.一 视图的出现

前面讲解了各种查询和子查询,如果要进行一个复杂功能的查询,那么就可能需要写很长很长的一个sql, 在代码中将这些sql进行硬编码进去,不便于后期维护和复用。 有没有一种技术,可以像使用表查询那样简单 (select * from 表名 ), 将那个很长很长的sql的查询结果封装到一个独特的表里面呢? 以后在查询的时候,直接查询那个独特的表即可? 实际上,数据库提供了这么一个技术, 这个技术叫做 视图 (view) .

视图(view) 和 表(table) 是有区别的。 表中的数据是一个真正存在的,存储于物理结构中, 而视图中的数据是虚拟的,
并不真实存在。

视图,常常适用于用于多个表连接查询之间的结果。

一.二 视图的优点

一.二.一 简单化

看到的,就是查询出来的。 直接 select * from 视图 即可, 并不需要向以前那样,写一个很长的sql语句(sql语句中,包括where,分组,排序等)

一.二.二 安全性

视图中只能查询和修改视图使用者所能看到的数据,不能维护其看不到的数据。 也就是, 表使用者和视图使用者,两个人的权限是不一样的, 从而保证了数据的安全性。

如在 user 表里面,存在以下数据:

	select * from user;

有图片。

共九个数据。

那么, 表使用者可以看到这九个员工, 同样,也可以维护 这九个员工的信息。

如果将

	select * from user where id=1;

有图片

这一条数据,封装成视图, 那么,视图使用者只能看到这一个姓名为 ‘两个蝴蝶飞’ 的数据,也只能维护这一个员工的信息, 不能维护他看不到的,如 ‘岳泽霖’ 等这些数据。 从而,保证了重要数据的安全性。

如 员工工资数据,只有财务部门可以看,人事部门是没有办法查看的。

一.二.三 逻辑数据独立性

可以屏蔽真实表的表结构信息。

如 查询真实表的话, select * from user, 那么用户就可以看到,这个表 user 里面有 id,name,sex,birthday,age,deptId 六个字段。

如将 :

	 select id,name from user ;

的查询结果封装成一个视图,如视图 v_user 的话, 那么在查询 视图 v_user 时,只会显示 id,name 两个字段, 从而避免了真实表 user 的数据结构。

如将

	 select a.id as uId,a.name as uName,d.id as dId,d.name as dName from user a
	  left join dept d on a.deptId=d.id; 

的查询结果封装成一个视图, 如视图 v_user_dept 的话, 那么在查询 视图 v_user_dept 时,只会显示 员工编号,员工名称 ,部门编号,部门名称 四个字段, 从而屏蔽了真实 user 表和 真实 dept 表中的字段。

一.三 视图的操作

视图,通常有以下几种操作

操作指令 代码
创建视图 create view 视图名 as sql查询
查看视图 describe 视图名 或者 show create view 视图名
修改视图 create or replace view 视图 as sql查询
使用视图 正常表 table 的使用
删除视图 drop view [if exists] 视图名
视图条件限制 with check option

下面,老蝴蝶 分别对每一种操作进行讲解。

视图,仍然使用的是 user 表和 dept 表进行讲解。

	use yuejl;
	select * from user;
	select * from dept;

有图片

二. 创建视图 create view view_name

二.一 创建的命令

创建视图的完整命令是:

	create [or replace] [algorithm={undefined|megre|temptable}]
	view view_name [{column_list}]
	as select_statement
	[with {cascaded|local} check option]

通常,会简写成:

	create [or replace]
	view view_name [{column_list}]
	as select_statement 

create 表示创建, or replace 表示 替换。 连用的话, create or replace 表示,如果存在这个视图名,就替换,
如果不存在,就创建。

其中,{column_list} 常常会省略,省略时,表示 视图中的字段名称 与 select_statement 中的字段名称一致。

其中,创建视图,可以在单表上,也可以在多表上。

二.二 单个表省略字段创建视图

如,查询员工的id,name,age 和 id和age的积 的值。

查询语句为:

	select id,name,age,id*age from user;

有图片

那么, 创建 单表视图, 如 v_user1 就是:

	create view v_user1
	as select id,name,age,id*age from user;

有图片

查询 视图 v_user1, 就像查询表 那么操作

	select * from v_user1;

有图片

其中, 视图的字段列表,就是查询的语句的字段列表。

二.三 单个表重新定义字段 创建视图

将视图的字段列表,重新定义, 不用原先的 查询表中的字段, 需要用到 [{column_list}]

	create view v_user2 (nId,nName,nAge,nIdAge)
	as select id,name,age,id*age from user;

有图片

再次查询时:

	select * from v_user2;

有图片

发现,视图字段就变成了新定义的字段列表了。

二.四 多个表创建视图

如,查询每个员工的编号,姓名,部门编号和部门的名称。

查询语句为:

	 select a.id as uId,a.name as uName,d.id as dId,d.name as dName from user a
	  left join dept d on a.deptId=d.id; 

有图片

创建视图 v_user_dept

	create view v_user_dept (uId,uName,dId,dName)
	as (select a.id as uId,a.name as uName,d.id as dId,d.name as dName from user a 
		left join dept d on a.deptId=d.id) ;

有图片

查询视图

	select * from v_user_dept;

有图片

会发现, 视图的查询,远比表连接查询,更简单,也更易复用。

三. 查看视图

如何像查看 表结构 那样, 查看视图结构呢?

三.一 describe view_name

如 查询刚才创建的 v_user1 视图

	describe v_user1;

有图片

与 describe 表名 查询出来的结构一致。

其中,也可以用其简写的形式, desc view_name

	desc v_user1;

有图片

三.二 show create view view_name

如 查询刚才创建的 v_user2 视图

	show create view v_user2 \G

有图片

与 show create table table_name 一致。

三.三 show table status like ‘视图名’

查看 视图结构的详细信息

如 查看 视图 v_user1

	show table status like 'v_user1' \G

有图片

comment 为 view 表示,是视图

如果是表的话, comment 显示的是 空字符串

	show table status like 'user' \G

有图片

三.四 information_schema 数据库下的 views 表

如 查询一下 v_user1 视图

	select * from information_schema.views t where t.table_name='v_user1' \G

有图片

information_schema.views, 表示去查询 information_schema 数据库下的 views 表(注意,此时仍然在 yuejl数据库中)

一般 使用 describe(desc) 视图名 进行查询视图的相关信息。

四. 修改视图

修改已经存在的视图,有两种方式,一种是 create or replace, 另外一种是用 alter .

四.一 create or replace 重新创建视图

修改视图,用的是 or replace ,会重新创建一个新的视图。

如 修改 视图 v_user1, 改变 查询 name 和 age 的视图。 不能改变视图名称,只改变查询结果。

	create or replace view v_user1(name,age)
	as (select name,age from user) ;

有图片

查询一下数据:

	select * from v_user1;

有图片

会发现,视图 v_user1 被修改了。

注意,此时如果视图名称不存在,那么将会创建一个新视图。

四.二 alter view view_name 重新创建视图

修改视图,而不是 存在时修改,不存在时创建,那么可以直接使用 alter 进行修改

如 修改 v_user2 ,让其只查询 id 和 name 两个列。

	alter view v_user2 (id,name)
	as (select id,name from user);

有图片

将 create or replace 替换成 alter .

重新查询 v_user2 的话:

	select * from v_user2;

在这里插入图片描述

问题1: 如果 alter 修改的是一个不存在的视图, 如 v_user100 时,会出现什么情况呢?

	alter view v_user100 (id,name)
	as (select id,name from user);

有图片

ERROR 1146 (42S02): Table ‘yuejl.v_user100’ doesn’t exist

会报错,提示视图不存在。

五. 使用/更新 视图

视图是一个虚拟表,没有存储数据,所以对视图数据的更新,实际上都转移到对基本表的更新上了。但是,不建议对视图进行更新操作, 只提倡查询。

五.一 查询数据

如 查询视图 v_user2

	select * from v_user2;

有图片

v_user2 里面,有两个字段, id 和 name.

五.二 插入数据

当前, user 表 还是9条数据, 没有发生改变。

	select * from user;

有图片。

往视图 v_user2 里面插入一条数据, id 是10, 名称为 新员工5.

	insert into v_user2(id,name) values(10,'新员工5');

有图片

这个时候,重新查看一下 v_user2 视图数据

	select * from v_user2;

有图片

查看一下基本表 user中的数据

	select * from user;

有图片

可以看出,正常的插入到视图(准确说是基本表)里面了.

五.三 更新数据

如将 视图 v_user2 里面的 id=10 新插入的那个数据 的员工名称 改变 ‘我是新来的员工5’

	update v_user2 set name='我是新来的员工5' where id=10;

有图片

查看一下基本表 user 中的数据

	select * from user;

有图片

五.四 删除数据

如将 视图 v_user2 里面的那条 id=10 的数据删除。

	delete from v_user2 where id=10;

有图片

再重新查询一下 user 表的数据

	select * from user;

有图片

五.五 约束性视图

在实际开发生活中,是不允许你通过更新视图进行改变基本表的数据, 所以常常会增加一些限制。

如 创建一个新视图 v_user3, 里面有 id 和 name 两个字段,但是有限制。

	create or replace 
	view v_user3 (id,name)
	as (select id,name from user where id<20)
	with check option;

有图片

从表里面查询出来的数据,必须要保证 id<20.

那么,此时 查询一下视图:

	select * from v_user3;

有图片

如果此时,往视图里面 添加 一条 id=100 的新数据(100>20)

	insert into v_user3 (id,name) values(100,'新约束员工');

有图片

ERROR 1369 (HY000): CHECK OPTION failed ‘yuejl.v_user3’

会发现,不能插入进去 。

如果此时,往视图里面添加 一条 id=11 的新数据 (11<20)

	insert into v_user3 (id,name) values(11,'新约束员工');

有图片

可以正确地插入

重新查询一下数据:

	select * from user;

有图片

添加 with check option 之后,维护后的数据不能确定视图的完整性。

六. 删除视图

命令:

	drop [if exists] view view_name;

如删除 视图 v_user3

	drop view v_user3;

有图片

再次查询视图 v_user3的话:

	select * from v_user3;

有图片

如果删除一个不存在的视图, 那么也会报错的。

删除视图,支持同时删除多个视图, 如再删除 v_user1和 v_user2

	drop view v_user1,v_user2;

有图片

视图是非常重要的,老蝴蝶建议一定要掌握其常见用法。

谢谢!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章