时间:2021-07-01 10:21:17 帮助过:26人阅读
那么视图有什么作用呢?
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和书上有很多例子来阐述这个问题,我们需要掌握的核心就是对视图的更新操作存在某些限制,不是所有视图都能够更新
SQL中定义一个视图的语法如下:
- <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查询表达式,如定义一个“好供应商”视图:
- <code class=" hljs sql"><span class="hljs-operator"><span class="hljs-keyword">create</span> <span class="hljs-keyword">view</span> good_supplier
- <span class="hljs-keyword">as</span> <span class="hljs-keyword">select</span> S.s#, S.status, S.city
- <span class="hljs-keyword">from</span> S
- <span class="hljs-keyword">where</span> s.status > <span class="hljs-number">15</span>;</span></code>
query expression也可以有聚合函数、集合操作等等,SQL定义View还支持在View后面跟上属性list作为属性名(当然也可以用select as做重命名实现),如为各部门的员工销售额统计创建一个视图:
- <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)
- <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)
- <span class="hljs-keyword">from</span> EMP, DEPT
- <span class="hljs-keyword">where</span> DEPT.d# = EMP.d#
- <span class="hljs-keyword">group</span> <span class="hljs-keyword">by</span> dname;</span></code>
对视图检索的语法和对表检索是一样的,都用select语句,如:
- <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>
这句话等价于对基表进行如下检索:
- <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
- <span class="hljs-keyword">where</span> EMP.d# = DEPT.d#
- <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>
大多数SQL的实现(Oracle、MySQL等)支持对单一关系上的简单视图做更新操作,简单视图是如下的视图:
注:这里所说的视图更新包含了update、insert、delete三个操作
但是我们发现即使是对单一关系上的简单视图做更新操作,也会出现问题,如在好供应商表中update某个供应商的status值:
- <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翻译成
- <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
后缀进行检查上述类似的逻辑错误,如果好供应商有如下定义:
- <code class=" hljs sql"><span class="hljs-operator"><span class="hljs-keyword">create</span> <span class="hljs-keyword">view</span> good_supplier
- <span class="hljs-keyword">as</span> <span class="hljs-keyword">select</span> S.s#, S.status, S.city
- <span class="hljs-keyword">from</span> S
- <span class="hljs-keyword">where</span> s.status > <span class="hljs-number">15</span>
- <span class="hljs-keyword">with</span> <span class="hljs-keyword">check</span> <span class="hljs-keyword">option</span>;</span></code>
那么如上所述产生逻辑错误的update语句便不满足检查条件,DBMS会通知用户执行失败
数据库复习4——视图
标签:数据库 视图 sql