View 這個物件可以視作是一個虛擬的表格,本身沒有實體的存在,只能透過 Data Dictionary 得知其相關資訊, View 的內容是由一個或多個 Table 所構成,主要的目的是為了增加資料庫的安全性以及簡化程式碼,例如在 emp 這個表格當中,裡面的薪資 (salary) 欄位是一個敏感性資料,那麼就可以建立一個 View ,內容包含了 emp 除了薪資 (salary) 以外的欄位,未來只要授權使用者只能查詢 View 而不直接查詢原始 emp 這個 Table ,這樣就可以用來保護敏感性資料。使用 create view 語法建立 v_emp , v_emp 是沒有包含薪資 (salary) 這個敏感性資料:
除此之外,當我們有一段 SQL 語法,裡面有些運算式或是 join 條件式,那麼也可以把這麼一段語法建立成 View ,之後如果需要撈取這部分的資料,只要簡單的查詢 View 就好,不用再執行一大段 SQL 語法了。例如 DBA 用來查詢 Redo Log 的語法,需要 join v$log 與 v$logfile 才能得到相關訊息:
這時就可以把上述語法建立成一個 View ,未來要查詢 Redo Log 相關資訊只需要查詢這個 View 就好,不用再執行這麼複雜的語法了:
雖然 View 簡化了 SQL 語法,但是實際上執行的還是原本複雜的語法,如果 SQL 效能上有問題的話,必須還是要回去優化原本的 SQL 語法,單就 View 本身不會有效能上的改善。
View 本身雖然是一個虛擬的存在,但實際上它的內容是可以有條件被更新的 (Insert 、 Delete 、 Update) ,只要 View 本身可以判斷此欄位是來自於原生哪一個 Table 的欄位,那麼就可以成功更新 View 的資料,在此要注意的是,雖然是對 View 做更新,但實際上是會把資料 Update 回原始的 Table ,例如將 v_emp 這個 View 做 Update ,把 employee_id=199 的 department_id 更新為 10 :
雖然是針對 v_emp 做 update ,但是我們回去查詢原始的 emp 這個 Table ,會發現 employee_id=199 的 department_id 被更新為 10 了:
v_emp 可以被更新是因為這個 View 的內容只是很簡單的來自於單一個 Table emp ,並且沒有經過任何修飾與運算,所以 View 可以很簡單的判斷要去更新哪一個 Table 的哪個欄位,如果是一個比較複雜的 View ,那麼就有可能沒有辦法直接透過 View 更新了,例如建立一個 View 的內容是關於產品的總銷售收入 (earnings) ,這個欄位是由總銷售數量與產品價格所相乘起來:
由於 earnings 欄位是一個經過運算出來的欄位,因此 View 無法判斷此欄位的正確來源,這個時候就沒有辦法對這個 View 的這個欄位做 Update 了:
如果不想讓 View 可以被更新的話,在建立時可以加上 with read only ,這樣 View 就只能唯獨不容許更新了:
除此之外, View 也可以加上 with check option ,用來限制這個 View 的內容只能在某些區間,即便更新了也不可以超出這個範圍,例如建立一個 View 限制 department_id >= 50 ,在有 with check option 的條件下,就不能把 department_id 更新為 50 以下:
View 本身也是一連串的 SQL 語法所構成,在建立的過程當中會檢查 SQL 語法是否正確,如果語法有問題, View 就無法建立,但是可以透過 force 來強制建立 View ,只不過建立起來後 View 的狀態是 compilation errors 仍然不可用,還是必須解決語法上的問題才行:
要得知 View 的相關資訊可以透過 dba_views 或是 user_views 來查詢:
沒有留言:
張貼留言