当前位置:Gxlcms > 数据库问题 > 数据库复习4——视图

数据库复习4——视图

时间:2021-07-01 10:21:17 帮助过:26人阅读

> VIEW (<relational_condition>) {<property_list>};

那么视图有什么作用呢?

  • 为hidden data提供安全性,即屏蔽某些不希望外界用户看到的机密数据
  • 提供一种简写的方式,有了视图的预先定义,某些时候能够避免写繁杂的select复合表达式
  • 让同一数据为不同用户同时从不同角度展示数据
  • 提供逻辑数据独立性,即当概念层的模式(基本表结构变化)发生改变时,外部层的模式不需要改变,因此外部的用户程序也不需要改变
  • 视图的定义结合了外部模式函数和外部层-概念层的映射函数
  • 视图为基表添加可扩展性
  • 视图也能完成对基表的重构

6.2 视图的操作

C.J.Date从形式化的角度来定义视图的两种操作:检索(Retrieval)和更新(Update)

定义在数据库(表)D上执行操作X得到视图V,即V=X(D),则对V视图进行检索就是R(V)=R(X(D))=X‘(D),也就是说对视图检索相当于对它的基表检索

需要注意的是如果V=X(D)被实现(Materializing)了,那么X(D)就是是基本表的一份拷贝,对V的操作和D独立开来;如果V=X(D)只是一个虚表,那么对V的操作会直接修改基本表D(大多数DBMS是采取后种方案)

如果定义U为更新操作,那么U(V)=U(X(D)),但是我们可以发现U(X(D))X(U‘(D))并不能等价,原因就是V的定义操作X可能涉及集合操作UNION或者from从句的JOIN等复杂操作,此时Update操作对于基本表来说存在歧义,是无法执行的

比如说V=A UNION B,去update一个元组到底是更新基表A中的元组还是更新基表B中的元组还是AB同时更新;又比如说去insert一个元组不满足B的完整性约束但满足A的完整性约束,是只插入A还是整个插入操作失败

PPT和书上有很多例子来阐述这个问题,我们需要掌握的核心就是对视图的更新操作存在某些限制,不是所有视图都能够更新

6.3 SQL视图

(1)创建视图

SQL中定义一个视图的语法如下:

  1. <code class=" hljs sql"><span class="hljs-operator"><span class="hljs-keyword">create</span> <span class="hljs-keyword">view</span> <view_name> <span class="hljs-keyword">as</span> <query expression>;</span></code>

query expression可以是任何合法的select查询表达式,如定义一个“好供应商”视图:

  1. <code class=" hljs sql"><span class="hljs-operator"><span class="hljs-keyword">create</span> <span class="hljs-keyword">view</span> good_supplier
  2. <span class="hljs-keyword">as</span> <span class="hljs-keyword">select</span> S.s#, S.status, S.city
  3. <span class="hljs-keyword">from</span> S
  4. <span class="hljs-keyword">where</span> s.status > <span class="hljs-number">15</span>;</span></code>

query expression也可以有聚合函数、集合操作等等,SQL定义View还支持在View后面跟上属性list作为属性名(当然也可以用select as做重命名实现),如为各部门的员工销售额统计创建一个视图:

  1. <code class=" hljs sql"><span class="hljs-operator"><span class="hljs-keyword">create</span> <span class="hljs-keyword">view</span> dept_summary(name, minsal, maxsal, avgsal)
  2. <span class="hljs-keyword">as</span> <span class="hljs-keyword">select</span> dname, <span class="hljs-aggregate">min</span>(sal), <span class="hljs-aggregate">max</span>(sal), <span class="hljs-aggregate">avg</span>(sal)
  3. <span class="hljs-keyword">from</span> EMP, DEPT
  4. <span class="hljs-keyword">where</span> DEPT.d# = EMP.d#
  5. <span class="hljs-keyword">group</span> <span class="hljs-keyword">by</span> dname;</span></code>

(2)视图检索

对视图检索的语法和对表检索是一样的,都用select语句,如:

  1. <code class=" hljs sql"><span class="hljs-operator"><span class="hljs-keyword">select</span> name <span class="hljs-keyword">from</span> dept_summary <span class="hljs-keyword">where</span> avgsal > <span class="hljs-number">2000</span>;</span></code>

这句话等价于对基表进行如下检索:

  1. <code class=" hljs sql"><span class="hljs-operator"><span class="hljs-keyword">select</span> dname <span class="hljs-keyword">as</span> name <span class="hljs-keyword">from</span> EMP, DEPT
  2. <span class="hljs-keyword">where</span> EMP.d# = DEPT.d#
  3. <span class="hljs-keyword">group</span> <span class="hljs-keyword">by</span> dame <span class="hljs-keyword">having</span> <span class="hljs-aggregate">avg</span>(sal) > <span class="hljs-number">2000</span>;</span></code>

(3)视图更新

大多数SQL的实现(Oracle、MySQL等)支持对单一关系上的简单视图做更新操作,简单视图是如下的视图:

  • 不包括以下操作:JOIN、UNION、INTERSECT、EXCEPT
  • 不包含关键字:DISTINCT
  • SELECT从句只能包含简单表名(即不包含聚合函数)
  • 不能出现GROUP BY从句
  • 子查询不能包含在查询以外的对同表的引用

注:这里所说的视图更新包含了update、insert、delete三个操作

但是我们发现即使是对单一关系上的简单视图做更新操作,也会出现问题,如在好供应商表中update某个供应商的status值:

  1. <code class=" hljs sql"><span class="hljs-operator"><span class="hljs-keyword">update</span> good_supplier <span class="hljs-keyword">set</span> status = <span class="hljs-number">10</span> <span class="hljs-keyword">where</span> S# = <span class="hljs-string">‘s1‘</span>;</span></code>

DBMS翻译成

  1. <code class=" hljs sql"><span class="hljs-operator"><span class="hljs-keyword">update</span> S <span class="hljs-keyword">set</span> status = <span class="hljs-number">10</span> <span class="hljs-keyword">where</span> status > <span class="hljs-number">15</span> <span class="hljs-keyword">and</span> S# = <span class="hljs-string">‘s1‘</span>;</span></code>

执行,而视图good_supplier的定义并没更改,那么执行了这句话供应商s1虽然在基础表中的status值变成10了,但是该供应商s1却再也不属于good_supplier了,逻辑上出错(更新了视图却直接删掉了元组)

SQL为了防止上述情况的发生,支持在视图定义时插入with check option后缀进行检查上述类似的逻辑错误,如果好供应商有如下定义:

  1. <code class=" hljs sql"><span class="hljs-operator"><span class="hljs-keyword">create</span> <span class="hljs-keyword">view</span> good_supplier
  2. <span class="hljs-keyword">as</span> <span class="hljs-keyword">select</span> S.s#, S.status, S.city
  3. <span class="hljs-keyword">from</span> S
  4. <span class="hljs-keyword">where</span> s.status > <span class="hljs-number">15</span>
  5. <span class="hljs-keyword">with</span> <span class="hljs-keyword">check</span> <span class="hljs-keyword">option</span>;</span></code>

那么如上所述产生逻辑错误的update语句便不满足检查条件,DBMS会通知用户执行失败

数据库复习4——视图

标签:数据库   视图   sql   

人气教程排行