一、視圖
在之前所學習過的所有的SQL語法之中,查詢操作是最麻煩的,如果程序開發人員將大量的精力都浪費在查詢的編寫上,則肯定影響代碼的工作進度,所以一個好的數據庫設計人員,除了根據業務的操作設計出數據表之外,還需要為用戶提供若干個視圖,而每一個視圖包裝了一條條復雜的SQL語句,視圖的創建語法如下:
CREATE [OR REPLACE] VIEW 視圖名稱 AS 子查詢;
范例:創建一張視圖
CREATE VIEW myview AS SELECT d.deptno,d.dname,d.loc,COUNT(e.empno) count,AVG(e.sal) avg FROM emp e,dept d WHERE e.deptno(+)=d.deptno GROUP BY d.deptno,d.dname,d.loc;
現在已經創建好了一張視圖,名稱為myview,所以現在查詢myview:
SELECT * FROM myview;
此時通過一個簡單的視圖查詢操作,就可以完成之前的復雜SQL語句的功能,所以視圖就是包裝了SQL查詢操作。
范例:創建一張包含簡單查詢語句的視圖
DROP VIEW myview; CREATE VIEW myview AS SELECT * FROM emp WHERE deptno=20;
可是以上的操作實際上是屬於一個視圖的替換操作,所以此時也可以使用另外一種語法:
CREATE OR REPLACE VIEW myview AS SELECT * FROM emp WHERE deptno=20;
此時表示的是,如果視圖存在則替換,不存在則創建一張新的視圖,視圖的概念雖然好理解,但是在創建視圖的時候存在兩個選項。
- 選項一:WITH CHECK OPTION
上面所創建的視圖,是存在一個創建條件的“WHERE deptno=20”,那么如果現在更新視圖中的這個條件呢?
UPDATE myview SET deptno=30 WHERE empno=7369;
此時更新的是一張視圖,但是視圖本身並不是一個具體的數據表,而且現在更新的操作又是視圖的創建條件,很明顯這樣的做法不可取,所以此時為了解決這個問題,可以加入WITH CHECK OPTION;
CREATE OR REPLACE VIEW myview AS SELECT * FROM emp WHERE deptno=20 WITH CHECK OPTION;
此時再次執行視圖的更新操作,出現以下錯誤提示:
ORA-01402: 視圖 WITH CHECK OPTIDN where 子句違規
意味着現在根本就不能去更新視圖的創建條件。
- 選項二:WITH READ ONLY
雖然使用WITH CHECK OPTION可以保證視圖的創建條件不被更新,但是其他的字段卻允許更新。
UPDATE myview SET sal=9000 WHERE empno=7369;
與之前的問題一樣,視圖本身不是具體的真實數據,而是一些查詢語句,所以這樣的更新並不合理,那么在創建視圖的時候建議將其設置為只讀視圖:
CREATE OR REPLACE VIEW myview AS SELECT * FROM emp WHERE deptno=20 WITH READ ONLY;
此時再次發出更新的操作,則直接提示如下錯誤:
ORA-01733: 此處不允許虛擬列
而且一定要注意的是,以上給出的是一個簡單的操作語句視圖,如果現在視圖中的查詢語句是統計操作,則根本就不可能更新。
CREATE OR REPLACE VIEW myview AS SELECT d.deptno,d.dname,d.loc,COUNT(e.empno) count,AVG(e.sal) avg FROM emp e,dept d WHERE e.deptno(+)=d.deptno GROUP BY d.deptno,d.dname,d.loc;
現在的信息是統計而來的,根本就不可能更新。
在一個項目之中,視圖的數量有可能超過表的數量,因為查詢語句會很多的。
二、同義詞
同義詞就是意思相近的一組詞語,對於同義詞的操作之前一直在使用,例如,現在有如下一個查詢語句:
SELECT SYSDATE FROM dual;
在之前說過“dual”是一張虛擬表,但是虛擬表也肯定應該有它的用戶,經過查詢可以發現,這張表是屬於SYS用戶的,但是這個時候就出現一個問題,在之前講解過,不同的用戶要想訪問其他用戶的表,則需要寫上“用戶.表名稱”,那么為什么此時scott用戶訪問的時候直接使用dual即可,而不是使用“sys.dual”呢,這個實際上就是同義詞的應用,dual表示的是sys.dual的同義詞,而同義詞在Oracle之中稱為SYNONYM,同義詞的創建語法如下:
CREATE [PUBLIC] SYSNONYM 同義詞的名稱 FOR 用戶名.表名稱;
范例:下面創建一個同義詞為myemp,此同義詞指向scott.emp
CREATE SYNONYM myemp FOR scott.emp;
此時創建成功之后,以后在sys用戶中就可以使用myemp這個同義詞的名稱了,但是這個同義詞只適合sys用戶一個人使用,其他用戶無法使用,因為創建的時候沒有使用PUBLIC,如果沒有使用,則表示創建的不是公共同義詞。
范例:創建公共同義詞
CONN sys/change_on_install AS SYSDBA;
DROP SYNONYM myemp; CREATE PUBLIC SYNONYM myemp FOR scott.emp;
CONN system/manager; SELECT * FROM myemp;
但是同義詞也只是Oracle自己的概念,知道就行了。
三、索引
索引的主要功能就是用於提升數據庫的操作性能。
下面通過代碼分析一個最簡單的索引操作的問題;
例如,在之前曾經寫過如下的操作語句:
SELECT * FROM emp WHERE sal>1500;
此時由於在sal上沒有設置索引,所以它的查詢過程是采用逐行判斷的方式完成的,這種操作隨着數據量的上升,則性能會出現越來越多的問題,但是如果說將數據排列一下呢?
例如,現在將工作在內存之中形成這樣的一種數據結構;
如果現在假設所有的數據都排列成以上的樹形結構的話,同樣的查詢,現在還會查詢全部記錄嗎?只會查詢部分。
在Oracle之中創建索引有以下兩種方式:
- 主鍵約束:如果一張表中的列上存在了主鍵約束的話,自動創建索引;
- 手工創建:在某一個操作列上指定一個索引;
范例:在emp.sal字段上創建索引
CREATE INDEX emp_sal_ind ON emp(sal);
雖然索引創建完成了,但是要想觀察出特點基本上是不可能的。
但是這種索引有一個最大的問題,即:如果要想實現性能的提高,則必須始終維持以上的一棵樹,那么如果說現在這棵樹上的數據需要頻繁修改的話,則代碼的性能肯定會有所降低。
所以一般索引只使用在不會頻繁修改的表中,而如果一張表上頻繁修改數據且又使用了索引的話,性能肯定會嚴重降低,所以性能的攬永遠都是相對的。
以上的索引只是Oracle十幾種索引中的一種,也是最簡單的一種,稱為B樹索引,還有位圖索引,反向索引,函數索引等等。