什么是视图
视图是存储在数据库中的查询的SQL语句;
视图是一个虚拟的表,是一个表中的数据经过某种筛选后的显示方式;
视图
是一个由select语句查询定义的虚拟表,不存放任何数据;和真实的表一样,视图也有列名称和行数据,但是视图并不在数据库中以存储的数据集的形式存在,它的数据来自于定义视图的查询所引用的表,并且是在引用视图的时候动态生成;通过视图看到的数据是存放在表中的数据;
在使用SQL语句访问视图的时候,它返回的数据是MySQL从其他表中动态生成的;
视图的特点
- 1、视图和表在同一个命名空间,视图名称唯一,不重复;
- 2、从数据库系统内部看,视图是由一张或多张表中的数据组成,从数据库系统外部看,视图是一张表;视图中的数据并不属于视图本身,而是属于基本的表,对视图可以像表一样进行insert,update,delete操作;
- 3、视图可以进行查询,但是新增、修改、删除数据会有限制;通过视图只能查询和修改能看见的数据;表修改或删除后,视图应该删除重建;
- 4、视图不能使用索引,不能对视图创建触发器,不能使用drop table命令删除视图;
- 5、视图可以被嵌套,一个视图中可以嵌套另一个视图;
视图的作用、优点
1、安全性
:视图可以隐藏一些数据,通过视图用户可以被限制在数据的不同子集上,用户不能看到表中的全部数据,只能看到视图中定义的数据,也只能查询和修改他们所能见到的数据;
2、简单性
:视图可以简化用户对数据的理解和操作,使复杂的查询变得简单,易于理解和使用;
经常使用的查询可以定义为视图,这样每次执行相同的查询时,直接使用一条简单的查询语句查询视图即可,不用再指定全部查询条件;
3、视图可以使数据库表和应用程序在一定程度上独立;没有视图的时候,应用程序直接与数据库表进行交互,有了视图,应用程序通过视图和数据库表进行交互,应用程序和数据库表被视图分割开了;
视图的两种实现
1、临时表算法:
将select语句的结果存放到临时表中,当需要访问视图时,直接访问这个临时表就可以了;
// 不使用视图,直接从表中查询:
mysql> select code, name from Oceania where name='Australia';
// 使用临时表模拟视图:
mysql> create temporary table TMP_Oceania as
-> select * from Country where Continent='Oceania';
mysql> select code, name from TMP_Oceania where name='Australia';
使用临时表模拟视图有明显的性能问题:优化器很难优化在临时表上的查询语句;
2、合并算法:
重写含有视图的查询,将视图的定义SQL直接合并进查询的SQL中;
mysql> select code, name from Country
-> where Continent='Oceania' and name='Australia';
可以在explain extended
后使用 show warnings
查看使用视图的查询重写后的结果;
采用临时表算法实现的视图,explain中会显示为派生表(derived);
如果视图中包含group by、distinct、任何聚集函数、union、子查询等,主要无法在原表记录和视图记录中建立一一映射的场景中,MySQL都使用临时表算法来实现视图;
要查看具体使用的视图算法,可以explain一条针对视图的简单查询:explain select * from viewName;
,select_type=dervied
就说明使用的是临时表算法;
视图的实现算法是视图本身的属性,和作用在视图上的查询语句无关,可以为一个视图指定使用临时表算法:creat algortihm=temptable view viewName as select ... ;
视图的创建、删除
- 创建视图:
create [or replace] view viewName[列名组] as 查询语句 with check option;
- 删除视图:
drop view viewName;
or replace
:若所创建的试图已经存在,ORACLE自动重建该视图;
使用视图操作数据
可更新视图
:指的是可以通过更新这个视图来更新视图涉及到的相关表;只要指定了合适的条件,就可以更新、删除、插入视图数据;
如果视图中包含group by、distinct、任何聚集函数、union、子查询等,主要无法在原表记录和视图记录中建立一一映射的场景中,MySQL都使用临时表算法来实现视图;使用临时表实现的视图就不能更新了;
更新视图的查询 也可以是一个关联语句,但是有一个限制:被更新的列必须来自同一个表中;
1、check option
子句:表示任何通过视图更新的行,都必须符合视图本身的where条件定义;所以不能更新视图定义列以外的列,否则会报错;
// 不使用check option子句
mysql> create view user_view as select * from user where user.sex='女';
mysql> insert into user_view(name, sex, age) values('zxj', '女', 25);
插入操作成功,但是不合理;
// 使用check option子句
mysql> create view user_view as select * from user where user.sex='女' with check option;
mysql> insert into user_view(name, sex, age) values('zxj', '女', 25);
插入操作失败;视图定义列只有sex列,不能更新name、age列数据;
2、通过视图添加表数据:insert into viewName(列1, 列2, ...) values();
视图是虚拟表,本身不存储数据,其数据来自于引用表,添加数据是存储于视图参照的数据表中;
插入条件:
- 用户有权限向数据表中插入数据;
- 视图只引用了表的部分字段,所以插入数据时,只能明确插入视图列的字段值;
- 视图列以外的列应该具备以下条件之一:允许为null、设有默认值、是标识字段、数据类型是timestamp或uniqueidentifer;
- 视图不能包括多个字段的组合;
- 视图不能包含使用统计函数的结果;
- 视图不能包含distinct、group by子句;
- 定义with check option子句,则插入数据应符合相应的条件;
- 若视图引用多个表,一条insert只能同一个基表表中的数据;
3、更新数据记录:update viewName set name='zxj1' where name='zxj';
4、删除数据记录:delete
使用视图删除记录,可以删除任何基表中的记录;但是必须指定在视图中定义过的字段来删除记录;
视图引用多个表时,无法使用delete删除数据;