什么是视图?
视图(View)是数据库中的一个虚拟表,它是由一个或多个基本表(Base Table)的行和列组成的。视图并不实际存储数据,而是根据基本表中的数据动态生成的。通过视图,我们可以以一种特定的方式查看和操作数据库中的数据,而不需要直接访问基本表。
视图保存SQL逻辑,而不保存真实的数据。
基本语法
############ 创建视图 ############
create or replace view user_v1 as
select id, username, phone_number, avatar
from `user`
where id <= 50;
############ 查询视图 ############
show create view user_v1; #查询视图的创建语句
select * from user_v1 where id >= 30;
############ 修改视图 ############ (or replace替换覆盖原来的视图)
[create or replace view user_v1 | alter view user_v1] as (一个查询语句);
############ 删除视图 ############
drop view if exists user_v1;
检查选项(对通过视图插入的数据做检查)
问题引出
以下面的视图为例,现在通过user_v1视图插入一条id > 50的行数据,之后select * from user_v1的查询看不到插入的数据,这是因为视图user_v1在创建的时候指定了id <= 50
create table user_view_tb (
id int primary key auto_increment,
name varchar(32),
age int
);
create or replace view user_v1 as
select id, name, age
from `user_view_tb`
where id <= 50;
insert into user_v1 values (100, 'zhangsan', 23);
select * from user_v1;
这个时候我们再插入一条id<50的记录 再次查看视图,就能看到相应的数据:
insert into user_v1 values (100, 'zhangsan', 23);
解决方法
加上限制条件 当使用WITH CHECK OPTOPN子句创建视图的时候,MYSQL会通过视图检查正在更改的每个行,例如插入、更新、删除,以使其符合视图的定义。MySQL允许基于另一个视图创建视图,它还会检查视图中的规则以保持一致性。检查的范围由 CASCADE(级联) 或者 LOCAL(当前) 来指定
create or replace view user_v1 as
select id, name, age
from `user_view_tb`
where id <= 50
#加上这个限制条件 cascade级联(不仅检查当前的视图 而且要检查父视图中的条件) local当前
with cascaded check option;
这个时候id>100的数据则无法再插入
cascade级联特性
检查选项cascade是有级联特性的,如果子视图有限制条件,那么在子视图插入数据的时候,也会连带检查父层视图的where限制条件(不管父视图有没有定义with check option)
local非级联特性
检查选项local没有级联特性,如果子视图有限制条件,那么在子视图插入数据的时候,只有当父视图有没有定义with check option,才会检查父层视图的where限制条件
视图更新的条件
要使视图能够更新,视图中的行与基础表中的行之间必须存在一对一的关系,如果视图包含以下任何一项,则该视图不可更新:
(1)聚合函数或窗口函数(SUM(), MIN(),MAX(),COUNT()等)
(2)DISTINCT
(3)GROUP BY
(4)HAVING
(5)UNION 或者 UNION ALL
案例
数据库表的安全性
为了保证数据库表的安全性,开发人员在操作tb_user表时,只能看到用户的基本字段,屏蔽手机号和邮箱两个字段
create view tb_user_view as
select id, name, profession, age, gender, status, createtime
from tb_user;
select * from tb_user_view;
简化操作
查询每个学生所选修的课程(三张表联查),这个功能在很多的业务中都有使用到,为了简化操作,定义一个视图
create view tb_stu_course_view as
select s.name, s.no, c.name
from student s, sc, course c
where s.id = sc.student_id and sc.course_id = c.id;
select * from tb_stu_course_view;