(十六)视图


视图(View),是一种有结构但是没有 真实数据 的虚拟表,它的结构来源不是自定义,而是从对应的基表中产生 ;

但是视图可以查询数据,从基表查询数据 ,只是视图自己本身不包含任何数据;


创建视图

# 基本语法
-- select 语句可以是各种查询语句
create view 视图名字 as select 语句 ;

# 创建单表视图(基表只有一个)
mysql> create view my_v1 as 
    -> select * from student ;
Query OK, 0 rows affected

# 创建多表视图(基表>=2)
# 当多个基表中有同名字段的时候,需要使用别名,不然创建失败
mysql> create view my_v2 as
    -> select * from student s left join class c on c.id = s.id ;
1060 - Duplicate column name 'id'

mysql> create view my_v2 as 
    -> select s.*,c.id c_id,c.name c_name from student s left join class c on c.id = s.id ;
Query OK, 0 rows affected

视图一旦被创建,系统就会在视图对应的数据库文件夹下面,创建一个对应的结构文件:fm文件


查看视图

  1. 查看视图结构

    视图是一张虚拟表,虚拟归虚拟,但终归是表,因此,之前表的操作,都可以使用 ;

    mysql> desc my_v2 ;
    +--------+-------------+------+-----+---------+-------+
    | Field  | Type        | Null | Key | Default | Extra |
    +--------+-------------+------+-----+---------+-------+
    | id     | int(11)     | NO   |     | 0       |       |
    | name   | varchar(10) | YES  |     | NULL    |       |
    | sex    | varchar(10) | YES  |     | NULL    |       |
    | c_id   | int(11)     | YES  |     | NULL    |       |
    | c_name | varchar(10) | YES  |     | NULL    |       |
    +--------+-------------+------+-----+---------+-------+
    5 rows in set
    
    -- view table 都行
    mysql> show create view my_v1 ;
    +-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | View  | Create View                                                                                                                                                                                 |
    +-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | my_v1 | CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `my_v1` AS select `student`.`id` AS `id`,`student`.`name` AS `name`,`student`.`sex` AS `sex` from `student` |
    +-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    1 row in set
    
    -- 旋转下
    mysql> show create view my_v2G
    *************************** 1. row ***************************
           View: my_v2
    Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL 
    SECURITY DEFINER VIEW `my_v2` AS select `s`.`id` AS `id`,`s`.`name` AS 
    `name`,`s`.`sex` AS `sex`,`c`.`id` AS `c_id`,`c`.`name` AS `c_name` from 
    (`student` `s` left join `class` `c` on((`c`.`id` = `s`.`id`)))
    1 row in set (0.01 sec)
    
    

使用视图

视图,我们知道它只有结构,不含有任何真实数据,其获取数据都是从基表获取 ;

我们可以把视图想成 美团外卖,而基表则是 商家,外卖本身自己没有任何商品,我们却可以问外卖要东西,原因都在于,外卖去问商家要商品了 ;

# 查询视图

mysql> select * from my_v2 ;
+----+-------+-----+------+--------+
| id | name  | sex | c_id | c_name |
+----+-------+-----+------+--------+
|  1 | andy  | 1   | NULL | NULL   |
|  2 | sas   | 1   | NULL | NULL   |
|  3 | white | 2   | NULL | NULL   |
|  2 | an    | 1   | NULL | NULL   |
|  5 | hany  | 1   | NULL | NULL   |
|  6 | yang  | 2   | NULL | NULL   |
|  7 | Wily  | 2   | NULL | NULL   |
| 11 | gery  | 2   | NULL | NULL   |
+----+-------+-----+------+--------+
8 rows in set

会发现和直接查基表,一毛一样!费半天劲,就为了这个?

其实不然,我们可以把复杂的查询,定义为视图,这样下次再次使用的时候,就直接对应的视图即可,无需再写复杂的查询语句 ;就像定义函数一样 ,为了复用性;


修改视图

视图本身不可修改,但是视图的来源可以修改 ;

修改视图,就是修改视图本身的来源语句(select语句) ;


语法: alter view 视图名字 as 新的 select 语句  ;


删除视图


语法: drop view 视图名字   ;

删除视图,关键字只能是 view ,不像 show 查看的时候,view table 随便用 ;


视图意义

  1. 视图相当于封装了 sql 语句

    将复杂的 sql 封装了,使用视图进行保存;

  2. 数据安全

    视图操作主要是针对查询的,删除视图,不会删除掉数据,这和删除基表有本质区别 ;

  3. 权限限制

    对外提供数据的时候,不直接提供基表给他们,因为,基表中信息太多,有些是隐私的,不希望给他们看;

    这时候,就可以使用视图,进行二次封装,挑选可以对外暴露的数据,封装进视图,然后对外提供视图 ;

    对外提供视图,把基表都隐藏了,权限控制!


新增视图数据

  1. 多表视图不能新增数据

  2. 单表视图可以增加数据

    但是视图中必须包含不能为空,或者没有没有默认值的字段,否则,你想啊,视图
    插入的字段是不完整,而那个字段由不可以为null,或者没有默认值,就会导致记录不合法;

数据插入,直接插入到视图来源的基表中;

其实,后面就会学,控制视图,控制视图只能查询数据,而不可以增删改数据,毕竟视图,只是提供给外部用来查询数据的;


删除视图数据

  1. 多表视图不能删除数据

  2. 单表视图可以删除数据

    语法跟直接删除表数据一样!


更新视图数据

  • 单表视图可以更新数据
  • 多表视图也可以更新数据

更新限制(with check option)

我们在创建视图的时候,是可以对视图字段进行限制的,比如限定 age 大于等于 30

create view my_v3 as 
-- 限定视图的数据,都是基表中 age 大于30的
select * from student where age > 30 
-- 对 age 进行限定,保证视图中已有的 age 不能更新为 小于 30 的 ;
with check option ;

然后,我们在更新视图的时候,系统会进行验证,保证数据更新以后,依然还可以从基表中查到数据,否则不允许更新 ;

还有对视图进行数据的操作时候,必须保证操作的数据,在视图中,而不是在基表中 ; 因为同一张基表,可以产生多个视图,要保证视图间独立,互相不影响 ;


视图算法

系统对视图以及外部查询视图的 select 语句的一种解析方式 ;

视图算法分为三种:

  1. Undefined:未定义(默认的),这不是一种实际使用算法,是一种推卸责任的算法,告诉系统,视图没有定义算法,你自己看着办 ;
  2. Temptable:临时表算法,系统应该先执行视图的 select 语句,后执行外部查询语句 ;
  3. Merge:合并算法,系统应该先将视图对应的 select 语句与外部查询视图的 select 语句进行合并,然后执行;(此算法效率高,当没有指定算加粗样式法的时候,默认选中

创建视图的时候,指定视图算法 ;

create algorithm = 算法名字 view 视图名字 as select 语句 ;

至于算法的选择,看情况,其实大部分情况下,我们都是希望,我们视图的 select 语句里面的子句是先执行,然后再执行外部 select 语句,否则,执行结果,给人一种莫名其妙的感觉,这时候,我们就需要在创建视图的指定算法为 temptable ;

但是假如你的视图 select 子句很前,比如是 where group by ,那么不指定算法,默认选中 merge 就行,反正合并以后,视图 select 语句本来就在前面,合并以后还是在前面,还提高效率 ;

原文地址:https://www.cnblogs.com/young-youth/p/11665633.html