oracle 中的資料結構

tolywang發表於2007-04-17
資料型別(datatype)是列(column)或儲存過程中的一個屬性。

Oracle支援的資料型別可以分為三個基本種類:字元資料型別、數字資料型別以及表示其它資料的資料型別。



字元資料型別

CHAR CHAR資料型別儲存固定長度的子符值。一個CHAR資料型別可以包括1到2000個字元。如果對CHAR沒有明確地說明長度,它的預設長度則設定為1.如果對某個CHAR型別變數賦值,其長度小於規定的長度,那麼Oracle自動用空格填充。

VARCHAR2儲存可變長度的字串。雖然也必須指定一個VARCHAR2資料變數的長度,但是這個長度是指對該變數賦值的的最大長度而非實際賦值長度。不需要用空格填充。最多可設定為4000個字元。

因為VARCHAR2資料型別只儲存為該列所賦的字元(不加空格),所以VARCHAR2需要的儲存空間比CHAR資料型別要小。

Oracle推薦使用VARCHAR2

NCHAR和NVARCHAR2 NCHAR和NVARCHAR2資料型別分別儲存固定長度與可變長度的字元資料,但是它們使用的是和資料庫其他型別不同的字符集。在建立資料庫時,需要指定所使用的字符集,以便對資料庫中資料進行編碼。還可以指定一個輔助的字符集[即本地語言集(National Language Set,簡稱NLS)]。NCHAR和NVARCHAR2型別的列使用輔助字符集。

在Oracle9i中,可以以字元而不是位元組為單位來表示NCHAR和NVARCHAR2列的長度。

LONG LONG資料型別可以存放2GB的字元資料,它是從早期版本中繼承來的。現在如果想儲存大容量的資料,Oracle推薦使用CLOB和NCLOB資料型別。在表和SQL語句中使用LONG型別有許多限制。

CLOB和NCLOB CLOB和NCLOB資料型別可以儲存多達4GB的字元資料。NCLOB資料型別可儲存NLS資料。

數字資料型別

Oracle使用標準、可變長度的內部格式來儲存數字。這個內部格式精度可以高達38位。

NUMBER資料型別可以有兩個限定符,如:

column NUMBER ( precision, scale)

precision表示數字中的有效位。如果沒有指定precision的話,Oracle將使用38作為精度。

scale表示數字小數點右邊的位數,scale預設設定為0.  如果把scale設成負數,Oracle將把該數字取捨到小數點左邊的指定位數。

日期資料型別

Oracle標準日期格式為:DD-MON-YY HH:MI:SS

透過修改例項的引數NLS_DATE_FORMAT,可以改變例項中插入日期的格式。在一個會話期間,可以透過ALTER SESSION SQL命令來修改日期,或者透過使用SQL語句的TO_DATE表示式中的引數來更新一個特定值。

其它的資料型別

RAW和LONG RAW RAW和LONG RAW資料型別主要用於對資料庫進行解釋。指定這兩種型別時,Oracle以位的形式來儲存資料。RAW資料型別一般用於儲存有特定格式的物件,如點陣圖。RAW資料型別可佔用2KB的空間,而LONG RAW資料型別則可以佔用2GB大小。

ROWID ROWID是一種特殊的列型別,稱之為偽列(pseudocolumn)。ROWID偽列在SQL SELECT語句中可以像普通列那樣被訪問。Oracle資料庫中每行都有一個偽列。ROWID表示行的地址,ROWID偽列用ROWID資料型別定義。

ROWID與磁碟驅動的特定位置有關,因此,ROWID是獲得行的最快方法。但是,行的ROWID會隨著解除安裝和過載資料庫而發生變化,因此建議不要在事務中使用ROWID偽列的值。例如,一旦當前應用已經使用完記錄,就沒有理由儲存行的ROWID.不能透過任何SQL語句來設定標準的ROWID偽列的值。

列或變數可以定義成ROWID資料型別,但是Oracle不能保證該列或變數的值是一個有效的ROWID.

LOB
LOB(大型物件)資料型別,可以儲存4GB的資訊。LOB有以下3種型別:

。CLOB,只能儲存字元資料

。NCLOB,儲存本地語言字符集資料

。BLOB,以二進位制資訊儲存資料

可以指定將一個LOB資料儲存在Oracle資料庫內,還是指向一個包含次資料的外部檔案。

LOB可以參與事務。管理LOB中的資料必須透過DBMS_LOB PL/SQL內建軟體包或者OCI介面。

為了便於將LONG資料型別轉換成LOB,Oracle9i包含許多同時支援LOB和LONG的函式,還包括一個ALTER TABLE語句的的新選擇,它允許將LONG資料型別自動轉換成LOB.

BFILE

BFILE資料型別用做指向儲存在Oracle資料庫以外的檔案的指標。

XMLType

作為對XML支援的一部分,Oracle9i包含了一個新的資料型別XMLType.定義為XMLType的列將儲存一個在字元LOB列中的XML文件。有許多內建的功能可以使你從文當中抽取單個節點,還可以在XMLType文件中對任何節點建立索引。

使用者自定義資料

從Oracle8以後,使用者可以定義自己的複雜資料型別,它們由Oracle基本資料型別組合而成。

AnyType、AnyData和AnyDataSet

Oracle包括3個新的資料型別,用於定義在現有資料型別之外的資料結構。其中每種資料型別必須用程式單元來定義,以便讓Oracle9i知道如何處理這些型別的特定實現。

型別轉換

Oracle會自動將某些資料型別轉換成其他的資料型別,轉換取決於包括該值的SQL語句。

資料轉換還可以透過Oracle的型別轉換函式顯示地進行。

連線與比較

在大多數平臺上Oracle SQL中的連線運算子用兩條豎線(||)表示。連線是將兩個字元值連線。Oracle的自動型別轉換功能使得兩個數字值也可以進行連線。

NULL

NULL值是關聯式資料庫的重要特徵之一。實際上,NULL不代表任何值,它表示沒有值。如果要建立表的一個列,而這個列必須有值,那麼應將它指定為NOT NULL,這表示該列不能包含NULL值。

任何資料型別都可以賦予NULL值。NULL值引入了SQL運算的三態邏輯。如果比較的一方是NULL值,那麼會出現3種狀態:TURE、FALSE以及兩者都不是。

因為NULL值不等於0或其他任何值,所以測試某個資料是否為NULL值只能透過關係運算子IS NULL來進行。

NULL值特別適合以下情況:當一個列還未賦值時。如果選擇不使用NULL值,那麼必須對行的所有列都要賦值。這實際上也取消了某列不需要值的可能性,同時對它賦的值也很容易產生誤解。這種情況則可能誤導終端使用者,並且導致累計操作的錯誤結果。

基本資料結構



表是關聯式資料庫中的一個基本資料結構。表就是行的集合。每行(row)包含一個或多個列。

從Oracle8企業版以後,就提供了分割槽選件,它允許將表和索引進行分割槽。利用分割槽,Oracle可從以下兩方面改善效能:

。Oracle不用去訪問那些不滿足查詢條件的分割槽

。如果分割槽中所有資料都滿足查詢條件,那麼Oracle將選擇全部資料而不需要對每行均進行字句檢查。

檢視

檢視(view)是Oracle中的一種由SQL語句構造的資料結構。SQL語句儲存在資料庫中,在查詢中使用一個檢視時,所儲存的查詢將得以執行,並向使用者返回基表(base table)中的資料。

檢視不包含資料,而是表示一些方法可以檢視查詢所指定的基表資料。

檢視有以下幾種用途:

。簡化對多個表資料的訪問

。可以保證表中資料的安全(如,建立包含WHERE子句的檢視就可以限制訪問表中的資料)

。將應用與表中某些特定的結構分離

檢視建立在基表集合的基礎之上,基表包括Oracle資料庫中的事實表或者其他檢視。如果檢視中的任何一個基表進行修改,那麼該檢視將無法繼續使用它們,因此檢視本身也無法再使用。

索引

索引(index)是用來加快訪問資料庫中記錄速度的一種資料結構。一個索引與一個特定的表相關,而且包含該表的一個或多個列的資料。

建立索引的SQL基本語法:

CREAT INDEX emp_idx1 on emp (ename,job);

其中,emp_idx1時索引名,emp是建立索引的表,ename和job時構成索引的列值。

除了索引資料以外,索引項中還為其相關行儲存了ROWID.ROWID是獲取資料庫行的最快方式,因此隨後資料庫行的獲取都是以這種最佳方式來完成。

Oracle中使用的4中型別的索引結構:標準B*-樹索引、反向鍵索引、點陣圖索引以及Oracle8i引入的基於函式的索引。Oracle使你可以對錶中的資料進行聚合,從而改善效能。

其它資料結構

序列(Sequence)

在多使用者資料庫中經常出現的大問題,就是很難為鍵或識別符號提供唯一的序號。在這種情況下,Oracle允許建立序列物件。

序列號可以用名字,一個遞增值或有關序列的其他一些資訊。序列獨立於任何表,因此多個表可以使用同樣的序列號。

同義詞(Synonym)

所有的Oracle資料庫的資料結構都儲存在一個特定的模式(schema)。模式是和一個特定的使用者名稱相關聯的,所有物件都透過帶有物件名的模式名得到引用。

例如,模式DEMO中有一個表名為EMP.如果想引用表EMP,那麼應該透過完整名DEMO.EMP來引用。如果沒有提供特定的模式名,那麼Oracle假定該結構處於當前使用者名稱的模式中。

叢集(Cluster)

叢集是一種能夠改善獲取效能的資料結構。叢集和索引一樣,不會影響表的邏輯檢視。

雜湊叢集(Hash Cluster)

資料設計

約束

約束(constraint)強制資料庫中某些資料的完整性。當給某列增加一個約束,Oracle自動確保不滿足此約束的資料是絕不能被接受的。

約束可以在建立或增加包括某列(透過關鍵字)的表時與列相關聯,或者在表建立後透過SQL命令ALTER TABLE來實現與該列的關聯。在Oracle8及以後的版本中支援以下5個約束型別:

NOT NULL

對於任何列都可以設為NOT NULL.如果在任何SQL操作中將一個NULL值賦給某個有NOT NULL約束的列,Oracle會為這個語句返回一個錯誤。

惟一性

主鍵

外來鍵

校驗

某些約束需要建立所以來支援。

約束可以是立即的或延遲的。立即約束(immediate constraint)只要有寫操作就會立即對受約束列產生影響;而延遲約束(deferred constraint)只有在對約束行產生變化的SQL語句執行完時才有強制作用。

對於某個特定表的約束可設定成暫時掛起。當再次啟動該約束操作時,再要求Oracle對該約束驗證所有資料,或者只是對新資料應用約束。在現有表中增加約束時,可以指定是否對錶中所有記錄進行約束校驗。
觸發器

觸發器是個程式碼塊,當某個表中發生了某種型別的資料庫事件時它就會被觸發,有以下3種事件會導致觸發器的觸發:

。資料庫UPDATE

。資料庫INSERT

。資料庫DELETE

例如,可以定義一個觸發器,從而在使用者改變某一行時,寫一個定製的審查記錄。

觸發器是在行一級被定義的。可以指定觸發器是對每一行觸發,或者對觸發該觸發器事件的SQL語句觸發。

觸發器的觸發有3個時機:

。在執行觸發事件之前                          

。在執行觸發事件之後

。非觸發事件

將前兩種時間選項與觸發器所觸發的行和語句的結合,則有4種可能的觸發器實現:在語句之前;在行之前;在語句之後;在行之後。

任何觸發器都可以有一個觸發器限制(trigger restriction)。觸發器限制是一個布林表示式,如果其值為FALSE,那麼就阻止觸發器觸發。

觸發器的定義和儲存都獨立於使用它們的表。因為觸發器包含邏輯,所以必須透過比SQL功能強的某種實現資料訪問的語言來寫。可以直接用PL/SQL或Java來寫觸發器,也可以透過呼叫其中任一種語言編寫的現有儲存過程來寫觸發器。

觸發器觸發是SQL語句執行的結果,該SQL語句修改了某個表中的行。觸發觸發器的操作可能是修改這個表中的資料,或者產生某些改變來觸發其他表的觸發器。這麼做的最後結果可能是以某種方法修改了資料,但Oracle認為這是不合邏輯的。這些情況都會導致Oracle返回變異表(mutating table,被其他觸發器修改的表)的執行時錯誤,或是返回約束表(constraining table,被其他約束脩改的表)的執行時錯誤。

Oracle8i還引入了一組非常有用的系統事件觸發器和使用者事件觸發器。現在可以在系統事件(如,資料庫啟動或關閉)中放置觸發器,也可以在使用者事件(登入和退出)中放置觸發器。

查詢最佳化

不用事先定義訪問資料的路徑是關聯式資料庫的一大優點。向Oracle資料庫提交一個SQL查詢時,Oracle必須確定如何訪問資料。因為Oracle要找到一種最佳的方式來檢索資料,所以進行決策的過程稱為查詢最佳化(query optimization)。這種檢索稱為執行路徑(execution path)。查詢最佳化的技巧就是在眾多可用的方式中選擇一種最有效的方式來獲得資料。

例如,即使對於只涉及一個表的查詢,Oracle也會採用下列方法之一:

。使用索引來查詢所請求的行的ROWID,然後從表中檢索這些行。

。對錶進行掃描並檢索行,稱為完全表掃描(full table scan)

雖然在通常情況下,使用索引來檢索資料要快得多,但在索引獲取值的過程中涉及到一個附加的I/O步驟來處理查詢。利用索引值來選擇滿足要求的行所需的I/O操作較少,比從表中獲取資料然後對資料執行選擇條件的效率高得多。

確定最佳化查詢執行計劃的另一個因數在於查詢中是否包含ORDER BY條件,從而使之能夠按預排序索引自動實現。相反的,如果表很小,最佳化器可能選擇讀資料庫中所有的記錄,而不是索引。

有兩種Oracle查詢最佳化器可供選擇:基於規則的最佳化器和基於開銷的最佳化器

基於規則的最佳化器

使用預先定義的規則集作為查詢最佳化的主要決策依據。

它的一個缺點是過分簡單化的規則集。該最佳化器有大約二十條規則,每個規則的權值相同。對於複雜的資料庫,基於規則的最佳化器的簡單規則無法做出最佳的選擇。

基於開銷的最佳化

為了改進SQL語句的最佳化效能,Oracle在Oracle7中引入了基於開銷的最佳化器。基於開銷的最佳化器比基於規則的最佳化器要複雜一些,它透過邏輯I/O運算元最小的原則來選擇查詢路徑

Oracle8及以後的版本預設最佳化器為基於開銷的最佳化器。為了正確衡量所有執行計劃的開銷,基於開銷的最佳化器對有關資料結構的組成進行統計。

統計

基於開銷的最佳化器透過使用自己內部的統計相關的規則和邏輯來反映資料庫中資料結構的狀態。這些統計與執行計劃中的表、列以及索引相關。

這些統計型別存放在資料字典的三個表中

這些統計型別可以單獨或組合或二者結合使用,從而確定一個執行計劃需要的所有I/O開銷。這些統計型別可以反映出表的大小和資料塊中沒有被使用的空間總量兩方面資訊;相應的,這些空間反映出檢索行所需要的I/O操作次數。索引統計反映索引樹的深度與廣度,而且反映樹中值的唯一性,使用該索引可以簡化資料的選擇。

Oracle及以後的版本透過SQL語句ANALYZE來蒐集這些統計資訊。在一個SQL語句中可以對錶、索引或叢集進行分析。收集統計資訊是耗費資源的工作,在某些方面,有點像建立索引。因為本身隱含的效果,ANALYZE命令有下面兩個選項:

COMPUTE STATSTICS

在整個資料結構中計算統計資料

ESTIMATE STATISTICS

指定行數或資料結構中的一個百分比來進行統計分析。

對於收集相關統計資訊,後一種選項比進行整個資料結構的計算所耗費的資源要少得多。

注意:基於開銷的最佳化器的精度取決於它所使用的統計的精度,因此應該將統計資訊的更新作為維護計劃的一個標準部分。

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1450779

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/35489/viewspace-84581/,如需轉載,請註明出處,否則將追究法律責任。

相關文章