1. 程式人生 > >java線程

java線程

所有 提取 特性 兩個 自動 通過 其他 view 子查詢

我曾遇到一個項目的數據庫中視圖比表還要多很多(表和視圖加起來上千個),幾乎每個表都有對應的視圖,而且有很多視圖長得相似,比如有些視圖關聯的表一樣,只是查詢列表多或少了一兩個字段。我敢斷定,這就是因為一些水平低劣的開發人員看現有表或視圖的數據不完全符合他的需要,就不假思索的拷貝過來改一下然後創建一個新的視圖完事兒,久而久之,自然會出現很多相似甚至相同的視圖。

在接手上述項目後,真正令我感到崩潰的是,查詢語句往往涉及多個視圖,且常常是相似的視圖定義中又引用了另一個相似的視圖,被引用的視圖中又引用了另一個相似的視圖……。總之就一個字——亂!有時候為了找與頁面上字段對應的數據庫字段得看完一堆的視圖定義才能找到,因此那段時間我特別厭惡視圖!並暗下決心:日後如果我能做主,絕不用視圖。

後來我換了公司,新接觸的項目數據庫中基本沒用視圖。結果沒過多久,我便發現代碼中有很多相似甚至重復的查詢語句,而且代碼中的查詢語句改起來也比較費勁,於是乎我對視圖的主觀意識發生了搖擺。我開始問自己:到底該不該用視圖?如果用,要怎麽用才合理?用了視圖到底會降低性能還是會提升性能?

最後我通過閱讀《Oracle Database Concepts》並反復實踐和揣摩,終於對視圖有所感悟。多學一點知識就少一點困惑,而我正是對視圖理論方面有了大致了解後才解開對視圖的各種困惑。本文第 1 節大部分內容是對官方手冊的簡化翻譯,也夾雜了一些我個人的體會,英語好的讀者也可以忽略本節直接閱讀原文。

1、視圖理論

視圖是對一或多個表或其他視圖中包含的數據的自定義呈現。視圖將查詢的輸出視為一個表,因此可以認為視圖就是存儲的查詢或虛擬表。視圖中包含行和列,就像一個真實的表,但不包含數據本身。視圖所引用的表被稱為基表,視圖總是呈現基表中最近的數據,視圖可支持更新數據,所有對視圖數據的更新都將被反映到視圖的基表中,並受到基表的完整性約束和觸發器的約束。

1.1、視圖的存儲

與表不同,視圖不需要分配存儲空間,視圖也不包含實際數據。視圖由查詢定義,該查詢從視圖基表中提取或導出數據。因為視圖是基於其他對象的,所以視圖只需要在數據字典中存儲定義視圖的查詢,而不需要額外的存儲空間。

1.2、視圖的作用

可通過視圖以不同的形式來顯示基表中的數據,而視圖的強大之處在於它能夠根據不同的用戶需求來對基表中的數據進行不同形式的整合。視圖的常見用途如下:

1、通過限制對基表中一組指定行或列的訪問,來提供額外的安全控制。
2、視圖允許通過表連接整合多個表中的相關行或列,構成一個新的數據集,從而達到隱藏數據復雜性的目的。
3、視圖提供了從多個表中查詢數據,而不必知道如何關聯這些表的可能,因而簡化了查詢的 SQL 語句。
4、重命名視圖的列或更改數據形式,不會影響視圖所引用的基表,這樣一來就能以不同的角度來呈現基表中的數據了。
5、保存復雜的查詢,一個查詢可能會對表數據進行復雜的計算,如果將這個查詢保存為視圖,那之後需求進行計算只需查詢該視圖即可。
6、表達不使用視圖無法表達的查詢,有時候用戶需求過於復雜,幾乎寫不出來僅從基表中查詢數據的單條 SQL 語句,如某些復雜的分組查詢、聯合查詢等。
簡單來說,合理運用視圖,不僅可以提高數據的安全性,還可以少寫代碼,提升開發效率和程序的可維護性,也有利於在某些情況下靈活高效的控制數據的展現形式。

1.3、視圖的工作機制

Oracle 將定義視圖的語句以文本的形式存儲在數據字典中。當用戶在 SQL 語句中引用了視圖時,Oracle 將完成以下三步動作:

1、將引用了視圖的語句與視圖的定義語句合並成一個語句。
2、在共享 SQL 區解析整合後的語句。
3、執行該語句。
如果共享 SQL 區中存在相似語句,Oracle 就不會重復解析,只有在共享 SQL 區中沒有相似語句時,Oracle 才會為該語句創建新的共享 SQL 區。因此引用了視圖的 SQL 語句也可能會節約內存進而提高查詢性能。

1.4、視圖的依賴性

定義視圖的查詢必須要引用其它對象(表、視圖),換而言之,視圖依賴於其所引用的對象而存在。Oracle 會自動地處理視圖的依賴關系。例如,當用戶刪除視圖的某個基表後再次創建它,Oracle 就會自動的去檢查新的基表是否符合現有的視圖定義,進而判斷視圖的有效性。在 PL/SQL Developer 中,所有 Oracle 認為無效的視圖都會被打上紅叉叉。

1.5、可更新的連接視圖

連接視圖是指在視圖定義的查詢的 FROM 字句中引用了多個表或視圖的視圖,而可更新的連接視圖是指能夠支持 UPDATE、INSERT 和 DELETE 操作的連接視圖。數據字典視圖ALL_UPDATABLE_COLUMNS、DBA_UPDATABLE_COLUMNS和USER_UPDATABLE_COLUMNS中包含了那些可更新的視圖列信息。如果要確保視圖可更新,那麽視圖定義中就不能包含以下語法結構:

1、集合運算符。
2、DISTINCT 運算符。
3、聚合函數或分析函數。
4、GROUP BY、ORDER BY、CONNECT BY 或 START WITH 子句。
5、SELECT 列表中的集合表達式。
6、SELECT 列表中的子查詢。
7、JOIN 連接(也有例外情況)。


Oracle 在對主表進行 DML 操作之後,會通過刷新來維護物化視圖中的數據(以確保物化視圖和基表中的數據同步)。刷新模式有兩種:ON DEMAND 和 ON COMMIT,而刷新方式有四種:FAST、COMPLETE、FORCE 和 NEVER。FAST 刷新采用增量刷新,只刷新自上次刷新以後進行的修改。COMPLETE 刷新對整個物化視圖進行完全的刷新。如果選擇FORCE 方式,Oracle 會在刷新前先判斷下是否可以進行快速刷新,如果可以則采用 FAST 刷新,否則采用 COMPLETE 刷新。NEVER 指物化視圖不進行任何刷新。

對於使用快速刷新方法的物化視圖,物化視圖日誌或直接加載日誌將保留對主表的更改記錄。已經創建好的物化視圖也還可以再修改它的刷新方式。物化視圖還可以按要求定期刷新。

物化視圖日誌是將更改同步到主表的模式對象。通過物化視圖日誌可以逐級刷新主表上定義的物化視圖,此過程被稱為增量或快速刷新。如果沒有物化視圖日誌,Oracle 必須重新執行物化視圖查詢來刷新物化視圖,這個過程稱為完全刷新。通常,快速刷新比完全刷新需要更少的時間。

物化視圖日誌位於和主表相同模式中的主數據庫中。每個主表上最多能定義一個物化視圖日誌。Oracle 可以根據物化視圖日誌對所有需要快速刷新的物化視圖執行快速刷新。要快速刷新物化連接視圖,必須為實例化視圖引用的每個表創建一個物化視圖日誌。

創建物化視圖日誌:

示例一(創建支持主鍵實例化視圖快速刷新的物化視圖日誌,並指定物理和存儲特性):
更多創建物化視圖的細節請參考:《Oracle Database SQL Reference: CREATE MATERIALIZED VIEW》。修改物化視圖的細節請參考:《Oracle Database SQL Reference: ALTER MATERIALIZED VIEW》。

java線程