- MySQL - 视图 view


什么是视图

视图是存储在数据库中的查询的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删除数据;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值