数据库视图探究

视图简介

基本概念

  • 基本表:是实际存储于存储文件中的表,基本表中的数据是需要存储的。
  • 视图:是在SQL中只存储其由基本表导出视图所需要的公式,即由基本表产生视图的映像信息,其数据并不存储,而是在运行过程中动态产生与维护的。对视图数据的更改最终要反映在对基本表的更改上。

视图的作用

  • 数据库视图隐藏了数据的复杂性。,让数据更加清晰。想要什么样的数据,就创建什么样的视图。

  • 数据库视图有利于控制用户对表中某些列的访问。可以对不同的用户,设定不同的视图。

  • 数据库视图使用户查询变得简单。视图就像一个函数,提高了各种操作的重用性。

视图的基本操作

以下操作都是基于sql server2016进行测试的。

视图的创建

视图需要“先定义,在使用”,简单来说就是在select查询语句前加上创建视图的语句,如下所示:

create view <视图名> [<列名>,<列名>...] as 
<子查询> 
[with check option]

中括号里面的语句是可缺省的,需要说明以下两点:

  • [<列名>...]中括号里面为视图的属性名,如果缺省,则默认为该视图为子查询结果中的属性名。

  • with check option则指明当对视图进行insert、update、delete时,要检查进行insert、update、delete的元组是否满足视图定义中子查询中定义的条件表达式,就是确保更新以后的视图与一开始定义的视图保持一致。

一个简单的例子:

-- 从学成成绩表中创建每个学生的平均成绩视图
CREATE VIEW avgGrade(sno,avg_grade) as 
select sno,AVG(grade) from E 
group by sno
with check option

视图的查询

视图就相当于一个虚拟表,所有对基本表的查询语句,对视图也同样适用。例如查询刚才创建的视图:

select * from avgGrade

视图的更新

这里提到的视图更新包括UPDATE,DELETE,INSERT三种操作,基本的语句也是与表的更新操作相同,但因视图不保存数据,对视图的更新最终要反映到对基本表的更新上,而有时,视图定义的映射是不可逆的。所以视图的更新是一个较为复杂的问题,我们放到最后单独分析。

视图的撤销

drop view <视图名> [cascade];

因为视图可能是另一个视图导出的,cascade 将删除由它导出的所有视图。

视图是否可更新?

答案是视情况而定。

通常,视图是可更新的(即可进行UPDATE,DELETE,INSERT)。对于由单一表的子集构成的视图,即如果视图是从单个基本表使用选择、投影操作导出的,并且包含了基本表的主键,则可以更新。并且更新一个视图将更新其基表

但是,并非所有视图都是可更新的。基本可以说,如果不能正确得确定被更新的基数据,则不允许更新(包括插入和删除)。这实际上意味着,如果视图定义中有情况操作,则不能进行更新:

  • 分组(group by 和having)
  • 联结
  • 子查询
  • unique
  • 聚集函数(Min(),Count(),Sum()等)
  • distinct
  • 导出计算列
  • 如果视图是由单个表的列构成的,但并没有包括主键,则不能更新

由此可见,我们之前创建的学生平均成绩视图因为使用了分组和聚集函数,所以是不能更新的。其实这种视图更新限制的机制也很好理解,如果视图更新平均成绩,那这个平均成绩要怎么反映到基表中呢?

需要强调的是,一般应将视图用于检索不用于更新

下面简单说明更新视图的一些细节问题。

  • insert操作时,因为视图不一定包含基本表中的所有列,所以,最终插入到基本表时,没有涉及到的列会被设为默认值。这里也间接说明了为什么没有主键的视图不能进行更新了。

  • 如果创建视图时加上了with check option,则使用update、insert、delete时会在where部分加上子查询的条件表达式。不满足条件则报错。这样可以确保更新以后的视图与一开始定义的视图保持一致。如果不添加这句话,则对视图进行insert、update、delete时,可以插入任何不违反基表约束的记录。
    例如:

    --创建学号为1102同学的不同学期的成绩视图
    create view Test as 
    select sno,semester,grade from E 
    where sno=1102 
    with check option  
    
    update Test set grade=90 where semester='202001'    --对视图进行update操作
    --相当于
    update Test set grade=90 where semester='202001' and sno=1102  --sno=1102被加到where部分
    

    这也说明对于没有where子句的视图,使用with check option是多余的。

posted @ 2020-12-30 21:11  wgjmcal  阅读(168)  评论(0编辑  收藏  举报