數據庫複習4——視圖

數據庫複習


CH6 視圖

6.1 視圖的概念

視圖是從一個或多個表(或視圖)導出的虛表,DBMS僅在數據字典中存放視圖的定義,而視圖的數據仍然實際存儲於導出它的基表

Tutorial D中定義視圖的基本語句如下:

VAR <view_name> 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中定義一個視圖的語法如下:

create view <view_name> as <query expression>;

query expression可以是任何合法的select查詢表達式,如定義一個“好供應商”視圖:

create view good_supplier 
as select S.s#, S.status, S.city 
from S
where s.status > 15;

query expression也可以有聚合函數、集合操作等等,SQL定義View還支持在View後面跟上屬性list作爲屬性名(當然也可以用select as做重命名實現),如爲各部門的員工銷售額統計創建一個視圖:

create view dept_summary(name, minsal, maxsal, avgsal)
as select dname, min(sal), max(sal), avg(sal)
    from EMP, DEPT
    where DEPT.d# = EMP.d#
    group by dname;

(2)視圖檢索

對視圖檢索的語法和對錶檢索是一樣的,都用select語句,如:

select name from dept_summary where avgsal > 2000;

這句話等價於對基表進行如下檢索:

select dname as name from EMP, DEPT 
where EMP.d# = DEPT.d#
group by dame having avg(sal) > 2000;

(3)視圖更新

大多數SQL的實現(Oracle、MySQL等)支持對單一關係上的簡單視圖做更新操作,簡單視圖是如下的視圖:

  • 不包括以下操作:JOIN、UNION、INTERSECT、EXCEPT
  • 不包含關鍵字:DISTINCT
  • SELECT從句只能包含簡單表名(即不包含聚合函數)
  • 不能出現GROUP BY從句
  • 子查詢不能包含在查詢以外的對同表的引用

注:這裏所說的視圖更新包含了update、insert、delete三個操作

但是我們發現即使是對單一關係上的簡單視圖做更新操作,也會出現問題,如在好供應商表中update某個供應商的status值:

update good_supplier set status = 10 where S# = 's1';

DBMS翻譯成

update S set status = 10 where status > 15 and S# = 's1';

執行,而視圖good_supplier的定義並沒更改,那麼執行了這句話供應商s1雖然在基礎表中的status值變成10了,但是該供應商s1卻再也不屬於good_supplier了,邏輯上出錯(更新了視圖卻直接刪掉了元組)

SQL爲了防止上述情況的發生,支持在視圖定義時插入with check option後綴進行檢查上述類似的邏輯錯誤,如果好供應商有如下定義:

create view good_supplier 
as select S.s#, S.status, S.city 
from S
where s.status > 15
with check option;

那麼如上所述產生邏輯錯誤的update語句便不滿足檢查條件,DBMS會通知用戶執行失敗

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章