【數據庫】oracle數據庫對象---->視圖

數據庫的真實數據都是存在於數據表中,數據表是反映現實世界的實體關係。但是,爲現實世界的所有關係創建數據表是不現實的。數據庫中的視圖解決了這一問題。視圖以物理數據未基礎,利用更靈活的策略來實現關係。接下來,我們將從:

視圖介紹、關係視圖的創建和使用、內嵌式圖的使用、對象視圖的使用、物化視圖的使用等幾個方面,

來學習視圖的知識,並掌握如何創建和使用各種視圖,同時對各種視圖之間的區別有清晰的瞭解。


1、視圖簡介:

1.1 什麼是視圖

視圖是由已經存在的數據,通過一定的運算規則,來獲得新的數據集合。這使得用戶可以更加靈活的自定義數據集合,視圖同時爲數據安全性提供了一種控制策略。

(1) 視圖的產生

之前一篇博文中講到了數據表的創建規則,由於遵循第三範式,表在設計時,應當避免數據冗餘,而另一方面,使用各種組合數據更加常用,設計規則卻禁止爲組合數據創建新的數據表。

比如:表employees存儲了員工的基本信息,其中包括了員工ID、員工姓名、職位、年齡、地址。表salary存儲了員工工資信息,其中包括了工資ID、員工ID、月份、工資、貨幣種類。

現在需要爲財務人員準備一個新的數據集合,該數據集合存儲了員工ID、員工姓名、員工年齡、月份及當月工資。很明顯,創建新表employee_salary,以滿足財務人員的需求是不可取的,此時,創建視圖來解決該問題是最佳途徑。

下圖演示了針對表employees每行數據,根據employee_id列值相等的條件,在表salary中篩選記錄,並最終組成新的數據集合。這種關係運算的存儲在視圖vw_employees終。對於用戶來說,只需要定義運算規則,而運算貴的載體-----視圖,並不存儲真實的數據。


(2)視圖的本質

從關係代數理論上來說,數據表可以看做關係。這種關係往往代表了現實世界的真實實體。而關係可以通過各種運算(交、差、並、投影)來獲得新的關係。

在查詢員工工資狀況的實例中,可以通過表之間的關係運算獲得財務人員所需的結果集合。該結果集具有臨時性,一旦使用完畢,即可丟棄。這些結果數據,並不形成真正的數據表,也不會持久化到數據庫中。視圖也不存儲查詢的結果,但是存儲了查詢的定義。也就是說,對於關係運算的運算步驟進行存儲。因此,視圖的本質就是關係運算的定義。


1.2 爲啥使用視圖咧

視圖是絕大部分數據庫開發中都會使用的概念。使用視圖大致有兩個方面的原因。

(1)封裝查詢

數據庫雖然可以存儲海量數據,但是在數據表設計上卻不可能爲每種關係創建數據表。例如:對於學生表,存儲了學生信息,學生的屬性包括學號、姓名、年齡、地址等信息;而學生成績表只存儲了學生學號、科目、成績等信息,現需要獲得學生姓名及成績信息,那麼久需要創建一個關係,該關係需要包含學生姓名、科目、成績。但爲該關係創建一個新的數據表,並利用實際信息進行填充,以備查詢使用,是不合適的。因爲這種做法很明顯的造成了數據庫中數據的大量冗餘。

視圖則是解決該問題的最佳策略,因爲視圖可以存儲查詢定義(或者關係運算),那麼,一旦使用視圖存儲了查詢定義,就如同存儲了一個新的關係。用戶可以直接對視圖中所存儲的關係進行各種操作,就如同面對的是真實的數據表。


(2)靈活的控制安全性

一個數據表可能含有很多列,但是這些列的信息,對於不同角色的用戶,可訪問的權限有可能不同。例如:在員工表中,可能存在着員工工號、姓名、年齡、職位、地址、社會關係等信息。對於普通用戶,有可能需要訪問員工表,來查看某個工號的員工的姓名、職位等信息,而不允許查看家庭地址、社會關係等信息;對於高級用戶,則需要關注所有信息,那麼,久涉及到數據表的安全性。

利用視圖可以靈活的實現這一策略,例如:可以首先創建名爲vw_employees的視圖,該視圖的查詢定義爲,選擇員工表中員工工號、姓名、職位等3列,這相當於在員工關係中,進行投影運算,即選擇員工工號、姓名、職位等3個屬性,形成新的關係。

同樣的,對於高級用戶,可以創建名爲vw_employees_hr的視圖,該視圖選擇員工表中所有列。

然後,對於兩種角色分別分配兩個視圖的查詢權限,與實際的數據表employees隔離開來,從而控制數據訪問的安全性。


2、創建和使用關係視圖

oracle中的視圖,按照創建和使用方式的不同,可以分爲四類:關係視圖、內嵌視圖、對象視圖和物化視圖。

關係視圖是4種視圖中最簡單,同時也最常用的視圖。關係視圖可以看做對簡單或複雜查詢的定義。他的輸出可以看做一個虛擬的表。

2.1 創建關係視圖

oracle視圖是作爲數據庫對象存在的。因此,創建之後也可以通過工具或數據字典來查看視圖的相關信息,接下來,要講解的是:關係視圖的創建和如何查看視圖的屬性信息。

(1)創建關係視圖

創建關係視圖應該使用create view命令,其語法形式如下所示:

create view 視圖名稱 as 查詢語句|關係運算

其中,create view是創建關係視圖的命令,其後緊跟視圖名稱;as 後面連接的是視圖的查詢定義(或者說關係運算)。

例子:在數據庫中存在着名爲employees的數據表,如需創建針對普通用戶的視圖vw_employees。該視圖僅可以訪問表中的員工ID、員工姓名,以及員工職位,那麼可以利用如下的SQL語句。

create view vw_employees as select employee_id, employee_name, employee_position from employees;

其中,create view 向數據庫發送創建視圖命令,as 關鍵字連接創建命令與視圖定義;select employee_id、employee_name和employee_position from t_employees用於獲取表t_employees中的employee_id、employee_name和employee_position 3 列。

(2)查看視圖定義

視圖一旦創建,其定義即可存在於數據庫中,可以通過PL/SQL Developer的veiws 窗口查看視圖VW_EMPLOYEES在數據庫中的信息。

如果是有數據字典,也可以在輸入SQL語句進行查詢,比如:

select view_name, text from user_views where view_name= 'VW_EMPLOYEES';

view                          text

vw_employee         select employee_id, employee_name, employee_position from employees

其中,view_name列爲視圖名稱,text列爲視圖定義。


2.2 使用關係視圖

視圖一旦創建,用戶可以像查詢數據表一樣查詢視圖中的數據,但是,對於插入和更新操作來說,情況則有些不同。

(1)查詢視圖

例子:在創建了視圖VW_EMPLOYEES之後,即可利用查詢語句來獲得視圖中所包含的數據,如下:

SQL>select * from vw_employeess;

(2)更新視圖數據

用戶可以利用update語句更新視圖中的數據,而視圖本身並不存儲數據,其數據來源於基礎數據表,因此,更新視圖數據,實際是更新基礎表中的數據。

例子:在員工視圖vw_employees中,現在需要將員工“劉俊”職位調整爲“高級工程師”,那麼可以直接更新視圖,響應的SQL語句:

SQL>update vw_employees set employee_position = '高級工程師' where employee_name='劉俊';

其中,update爲更新命令;vw_employees爲update 命令的操作對象;set employee_position = '高級工程師',employee_name='劉俊',是指定更新條件。

但是,此時更新的實際是將表employees中的數據進行了修改。

綜合視圖操作及查詢結果可知,對視圖的更新操作,實際爲更新基礎表中的數據,由於視圖僅存儲查詢定義,因此,一旦基礎表中的數據被修改,則修改後的結果可以立即反映到視圖中。

2.3 向視圖插入數據

同樣,可以利用insert語句,向視圖中插入數據。

例子:在視圖vw_employees中,插入新員工“張三”的相關信息,其SQL語句如下所示。

SQL>insert into vw_employees values (6 , '張三', '測試工程師')

由於,該視圖只能查到該3項內容,所以,在向視圖vw_employees中插入數據時,無法爲列employee_age和列employee_address指定數據,因此,在基礎表employees中,對應記錄的employee_age列和employee_address列的值爲空。

2.4 總結利用關係視圖修改數據。

利用關係視圖,除了插入數據和更新數據之外,還可以刪除其中的數據。表面上看起來,可以通過視圖對基礎表進行任何修改,但事實並非如此,與之相反,大多數時候,並不能直接利用視圖修改基礎表數據。

例子:oracle內置視圖user_update_columns定義了用戶視圖中各列的可更新情況,可以通過如下SQL語句進行查看。

SQL>select table_name, column_name, updatable, insertable, deletable 

from user_updatable_columns

where table_name = 'VW_EMPLOYEES'

其中,TABLE_NAME列爲表名(在此,爲視圖名,這裏也印證了oracle往往將視圖當做普通數據表處理);COLUMN_NAME列爲視圖中的列名;UPDATBALE、INSERTABLE和DELETABLE分別代表列的可更新、可插入以及可刪除的情況。

對於更新操作,只要該列可更新,那麼飢渴利用視圖進行更新;而對於插入和刪除操作,則必須所有列均可執行插入和刪除操作,才能利用視圖進行操作。


2.3 修改/刪除視圖

在創建了關係視圖vw_employees之後,可以對其進行修改和刪除操作。

(1)修改視圖

修改視圖的過程即爲重新定義視圖的過程。可以通過首先刪除視圖,然後再次創建實現。另外,oracle也提供了一個專門的命令----create or replace view 來重新定義視圖。其語法形式如下所示:

create or replace view 視圖名稱  as  查詢語句 | 關係運算

例子:假設現在需要爲視圖vw_employees添加新列employee_age,那麼可以利用如下SQL語句。

create or repalce view vw_employees as

select employee_id, employee_name, employee_position, employee_age from employees

其中,create or replace view vw_employees用於創建或者替換視圖vw_employees的定義;as 之後的查詢語句爲視圖的新定義,在新定義中增加了列employee_age。

【注意】create or replace view命令的作用,當同名視圖不存在時,將執行創建命令;否則將執行替換命令。

(2)刪除視圖

刪除視圖的動作實際爲刪除數據庫中的對象操作,因此該操作爲DML操作,如同刪除數據表對象,刪除視圖也應該使用drop命令,其語法形式如下所示。

drop view view_name

其中,drop view向數據庫發送刪除視圖命令;view_name則指定了要刪除的視圖名稱。

例子:如需刪除視圖vw_employees,則可以利用如下SQL語句。

drop view vw_employees;


2.4 只讀視圖

上面講述了修改視圖數據,有時,並不希望用戶通過視圖修改數據,則可以創建只讀視圖,創建只讀視圖應該使用read only選項,其基本語法形式如下所示。

create or replace view 視圖名稱 as查詢語句

with read only

其中,with read only 選項表示該視圖將被創建爲只讀視圖。


2.5 聯接視圖

對於視圖定義來說,其數據可以來源於一個數據表,也可以來源多個數據表或者其他視圖的聯接。事實上,聯接視圖在實際開發中更加常用,本節將講述聯接視圖的使用。

例子:可以利用create or replace view定義一個聯接視圖,只是視圖定義更加複雜而已,在表employees與表salary中分別定義了員工與工資信息,則可以利用create or replace view創建視圖。

create or replace view vw_employee_salary as

select e.employee_id, e.employee_name, s.month, s.salary

from employees e, salary s

where e.employee_id = s.employee_id

其中as關鍵字之後使用了表employees與表salary的聯接獲得新的數據集合。聯接條件爲表employees中的employee_id與表salary中的employee_id相等。在視圖創建成功之後,即可查詢表中的數據。


2.6 強制創建視圖

歸根結底,視圖數據的來源是基礎數據表。有時,視圖的基礎表尚未創建,但是仍然希望創建基於不存在的數據表的視圖。

例子:開發者預期有名爲customer的數據表,該表至少包含以下列。

現需要創建一個名爲vw_customer的視圖,該視圖僅包含以下列customer_id、customer_code、customer_name、customer_level和contact_telephone。但是,視圖創建者無權創建實際的數據表。但是又不能等待表的預期創建者的工作,此時,可以使用force選項來強制創建視圖。利用force選項,強制創建視圖的語法如下所示。

create or replace force view 視圖名稱 as 查詢語句 | 關係運算

在PL/SQL Developer中強制創建視圖vw_customer。

SQL>create or replace force view vw_customer as

select customer_id, customer_code, customer_name, contact_telephone

from customer;







































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