视图(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文件
;
查看视图
-
查看视图结构
视图是一张虚拟表,虚拟归虚拟,但终归是表,因此,之前表的操作,都可以使用 ;
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
随便用 ;
视图意义
-
视图相当于封装了
sql
语句将复杂的
sql
封装了,使用视图进行保存; -
数据安全
视图操作主要是针对查询的,删除视图,不会删除掉数据,这和删除基表有本质区别 ;
-
权限限制
对外提供数据的时候,不直接提供基表给他们,因为,基表中信息太多,有些是隐私的,不希望给他们看;
这时候,就可以使用视图,进行二次封装,挑选可以对外暴露的数据,封装进视图,然后对外提供视图 ;
对外提供视图,把基表都隐藏了,权限控制!
新增视图数据
-
多表视图不能新增数据
-
单表视图可以增加数据
但是视图中必须包含不能为空,或者没有没有默认值的字段,否则,你想啊,视图
插入的字段是不完整,而那个字段由不可以为null
,或者没有默认值,就会导致记录不合法;
数据插入,直接插入到视图来源的基表中;
其实,后面就会学,控制视图,控制视图只能查询数据,而不可以增删改数据,毕竟视图,只是提供给外部用来查询数据的;
删除视图数据
-
多表视图不能删除数据
-
单表视图可以删除数据
语法跟直接删除表数据一样!
更新视图数据
- 单表视图可以更新数据
- 多表视图也可以更新数据
更新限制(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
语句的一种解析方式 ;
视图算法分为三种:
- Undefined:未定义(默认的),这不是一种实际使用算法,是一种推卸责任的算法,告诉系统,视图没有定义算法,你自己看着办 ;
- Temptable:临时表算法,系统应该先执行视图的
select
语句,后执行外部查询语句 ; - Merge:合并算法,系统应该先将视图对应的
select
语句与外部查询视图的select
语句进行合并,然后执行;(此算法效率高,当没有指定算加粗样式法的时候,默认选中)
创建视图的时候,指定视图算法 ;
create algorithm = 算法名字 view 视图名字 as select 语句 ;
至于算法的选择,看情况,其实大部分情况下,我们都是希望,我们视图的 select
语句里面的子句是先执行,然后再执行外部 select
语句,否则,执行结果,给人一种莫名其妙的感觉,这时候,我们就需要在创建视图的指定算法为 temptable
;
但是假如你的视图 select
子句很前,比如是 where
group by
,那么不指定算法,默认选中 merge
就行,反正合并以后,视图 select
语句本来就在前面,合并以后还是在前面,还提高效率 ;