0、LARGE OBJECT
Oracle8中有4種LOB
- BLOB:Binary Large Object
- CLOB:Character Large Object
- NCLOB:固定長(zhǎng)度的多字節(jié)Character Large Object
- BFILE:DB外部的二進(jìn)制文件
它們分為兩類:
內(nèi)部LOB:存放在DB內(nèi)部,包括BLOB,CLOB,BCLOB
外部文件:存放在DB外面,就是BFILE
要注重的是ORACLE8不自動(dòng)轉(zhuǎn)換這些類型的數(shù)據(jù)。
1、LONG和LOB的比較
LONG/LONG RAW LOB
--------------------------------------------------
表中只能由一個(gè)列 可以有多列
最大2G 最大4G
SELECT返回值 SELECT返回指針
存放在DB內(nèi) 可以在DB的內(nèi)或者外
不支持OBJECT類型 支持
順序存取 隨機(jī)存取
--------------------------------------------------
NCLOB不支持OBJECT類型
LOB小于4000字節(jié)時(shí)是內(nèi)部存放
2、LOB解析
LOB有兩個(gè)不同的部分
- LOB值:LOB代表的數(shù)據(jù)
- LOB指針:LOB存放數(shù)據(jù)的位置
LOB列內(nèi)部不存放數(shù)據(jù),而是LOB值的位置。當(dāng)創(chuàng)建內(nèi)部LOB時(shí),值存放在LOB SEGMENT中,指向OUT-OF-LIN數(shù)據(jù)的指針?lè)旁诹兄小?duì)外部LOB,只在列中存放位置。
3、內(nèi)部LOB
就是存放在DB內(nèi)部的LOB,包括BLOB,CLOB,NCLOB。它們可以是
用戶自定義的類型中的屬性
表中某列
SQL 變量
程序host變量
PL/SQL中的變量、參數(shù)、返回值
內(nèi)部LOB可以使用ORACLE的并發(fā)機(jī)制、REDO LOG、RECOVERY機(jī)制。
BLOB被ORACLE8解釋為二進(jìn)制位流,類似LONG RAW。
CLOB解釋為單字節(jié)字符流
NCLOB是固定的多字節(jié)字符流,基于DB NATIONAL字符集的字節(jié)長(zhǎng)度。
例子:
CREATE TYPE picture_typ AS OBJECT (image BLOB);
CREATE TABLE person_tab
( pname VARCHAR2(20),
RESUME CLOB,
picture picture_typ
);
上面的語(yǔ)句完成后,數(shù)據(jù)將存放在5個(gè)物理SEGMENT中。
- TABLE person_tab在缺省TABLESPACE,
- RESUME存放的LOB SEGMENT
- PICTURE存放的LOB SEGMENT
- 標(biāo)示RESUME存放位置的LOB INDEX SEGMENT
- 標(biāo)示PICTURE存放位置的LOB INDEX SEGMENT
LOB INDEX是隱式創(chuàng)建的。
當(dāng)INSERT或者OBJECT CACHE中的OBJECT刷新到SERVER時(shí),LOB生成。可以使用DBMS_LOB包和OCI來(lái)處理LOB。當(dāng)ROW刪除時(shí),相應(yīng)的內(nèi)部LOB也會(huì)刪除。UPDATE必須處理整個(gè)LOB值,不能UPDATE其中的一部分。
4、內(nèi)部LOB的存儲(chǔ)參數(shù)
具體語(yǔ)法可以參見(jiàn)ORACLE文檔,
LOB ( lob項(xiàng),...) STORE AS lob_segment_name
CHUNK integer
PCTVERSION integer
CACHE
NOCACHE LOGGING/NOLOGGING
TABLESPACE tablespace_name
STORAGE storage子句
INDEX INDEX字句
lob_segment_name:缺省式LOB$n
CHUNK:連續(xù)分配在一起的BLOCK數(shù)目,存放連續(xù)的LOB數(shù)據(jù)。這些CHUNK的數(shù)據(jù)存放在LOB INDEX里面,使用內(nèi)部LOB標(biāo)示和LOB值作為鍵。
PCTVERSION:LOB一致讀需要的系統(tǒng)空間。一旦LOB申請(qǐng)超過(guò)PCTVERSION的值,ORACLE就會(huì)收舊的空間并REUSE之。
CACHE:使用SGA區(qū)的DB BUFFER CACHE處理LOB的READ/WRITE。
NOCACHE LOGGING:不使用SGA區(qū)的BUFFER,數(shù)據(jù)的改變紀(jì)錄到REDO LOG。
存取LOB比較頻繁時(shí),使用CACHE
存取LOB不頻繁時(shí),使用NOCACHE
NOCACHE NOLOGGING:不使用SGA區(qū)的BUFFER和REDO LOG
INDEX子句
INDEX lob_index_segtment_name
INITTRANS integer
MAXTRANS integer
TABLESPACE tablespace_name
STORAGE storage子句
假如沒(méi)有設(shè)置LOB存儲(chǔ)參數(shù)和INDEX STROAGE,則采用如下缺省值
CHUNK=1 DB_BLOCK
PCTVERSION=10
NOCACHE
NOLOGGING
例子:
CREATE TABLE APARTMENTS (
floor_plan BLOB,
contract CLOB,
name VARCHAR2(10))
LOB (floor_plan, contract)STORAGE AS(
STORAGE (INITIAL 100K NEXT 100K PCTINCREASE 0)
CHUNK 10
PCTVERSION 20
NOCACHE
NOLOGGING
INDEX (INITIAL 100K NEXT 100K)
);
5、內(nèi)部LOB的并發(fā)
LOB的讀一致和其他ORACLE類型一樣,但是它是在CHUNK級(jí)別上作VERSION的。
6、外部LOB
ORACLE8答應(yīng)定義BFILE類型,可以把外部文件和BFILE對(duì)象連接起來(lái),同時(shí)能提供BFILE的安全機(jī)制。
BFILE對(duì)處理不需要transaction控制的OS文件很有用處。
對(duì)BFILE的處理需要DBMS_LOB或者OCI。
BFILE必須是READ-ONLY的,文件應(yīng)該放在ORACLE能存取的地方。假如刪除BFILE對(duì)象,外部文件并不刪除。
例子:
CREATE TABLE home_page(
EMPLOYEE REF EMPLOYEE_TYP,
LAST_UPDATE DATE,
HOMEPAGE BFILE);
CREATE TYPE personal_info_typ AS OBJECT
( EMPLOYEE REF employee_typ,
PICTURE BFILE,
THUMBPRINT BFILE,
REINAPRINT BFILE
);
其實(shí)在BFILE對(duì)應(yīng)的列或者屬性中存放的是BFILE的位置,即是物理文件的位置。
讀BFILE不通過(guò)SGA.
7、BFILE的安全
ORACLE8提供安全機(jī)制。文件必須和DB在一臺(tái)機(jī)器上,讀取不存在文件的timeout由os決定。可以和內(nèi)部LOB的讀取方法一致,但是必須注重:文件的權(quán)限、文件系統(tǒng)空間限制、其他對(duì)文件的維護(hù)、OS答應(yīng)的最大文件大小。
ORACLE8不對(duì)BFILE采取TRANSACTION的支持,ORACLE的BACKUO和RECOVERY也不支持BFILE。
8、目錄DirectorY
這是ORACLE為了治理BFILE引入的新元素,它指定SERVER文件系統(tǒng)的目錄,可以把文件系統(tǒng)的目錄抽象為數(shù)據(jù)庫(kù)對(duì)象,更具有靈活性。
DIRECTORY由DBA建立,系統(tǒng)用戶擁有,通過(guò)GRANT/REVOKE來(lái)確定哪些用戶有權(quán)限。
CREATE OR REPLACE DIRECTORY 目錄名 AS 路徑名
DROP DIRECTORY 目錄名
存取BFILE在如下情況時(shí)候產(chǎn)生異常:
-用戶沒(méi)有操作DIRECTORY的權(quán)限
-DIRECTORY所對(duì)應(yīng)的物理目錄不存在,或者沒(méi)有存取該目錄的權(quán)限。
-文件不存在
文件和權(quán)限的檢查是在文件存取時(shí)候檢查的,創(chuàng)建時(shí)候并不報(bào)錯(cuò)。
不支持邏輯路徑
系統(tǒng)新增加了CREATE ANY DIRECTORY和DROP ANY DIRECTORY。對(duì)DIRECTORY授權(quán)只有READ。
對(duì)CREATE DIRECTORY和GRANT READ ON DIRECTORY是可以AUDIT的。
8、DIRECTORY建立的原則
DIRECTORY不要和DB DATAFILE在相同的目錄下。
要有選擇的賦予CREATE ANY DIRECTORY和DROP ANY DIRECTORY ROLE。
在建立之前要在OS級(jí)別上設(shè)置權(quán)限。
假如移植DB到其他機(jī)器,需要注重DIRECTORY的路徑是否改變。
9、治理LOB
ORACLE 通類似文件操作一樣的接口:DBMS_LOB, OCI8。同時(shí)還有SQL語(yǔ)句的一些支持。
治理LOB的一般方法:
1)CREATE/POPULATE 包含LOB的TABLE,
2)在程序中DECLARE AND INITIALIZE LOB Locator
3)用SELECT FOR UPDATE 鎖定包含LOB的ROW,
4)用DBMS_LOB或者OCI維護(hù)相關(guān)LOB值
5)COMMIT
治理BFILE的一般方法
1)建立OS目錄,授予ORACLE 用戶READ的權(quán)限
2)把文件放到該目錄
3)建立包含BFILE的TABLE
4)建立DIRECTORY,用GRANT授權(quán)
5)在TABLE中INSERT與文件相關(guān)的值
6)在程序中聲明LOB Locator
7)取得包含LOB Locator的行
8)用DBMS_LOB和OCI讀取BFILE
10、LOB的操作
可以用SQL、PL/SQL、3GL中嵌入式SQL或者OCI中的變量值直接INSERT 到LOB中。
可以用其他的LOB、NULL或者EMPTY_CLOB()/EMPTY_BLOB()的值UPDATE LOB。當(dāng)把一個(gè)LOB賦給另一個(gè)時(shí),其實(shí)是新建了一個(gè)LOB。這些操作不需要SELECT FOR UPDATE。只有在更新LOB的其中一部分的時(shí)候才需要先LOCK。
ORACLE8不會(huì)自動(dòng)轉(zhuǎn)換CLOB和BLOB。
最好的辦法是OCILobWrite,以為它使用ORACLE的流機(jī)制,最快、使用更好的空間和REDO。
刪除LOB的方法
DELETE ....
TRUNCATE TABLE....
DROP TABLE ...
刪除后注重在OS級(jí)別上刪除相關(guān)文件。
假如只是要去掉LOB的Locator,可以用NULL或者空字符串''來(lái)UPDATE。
11、DBMS_LOB包
DBMS_LOB包用SYS用戶提交DBMSLOB.SQL和PRVTLOB.PLB腳本。它們包含在CATPROC.SQL中。用戶要授權(quán)才能使用它。匿名BLOCK中的DBMS_LOB例程使用當(dāng)前用戶的權(quán)限。STORED PROCEDURE中的DBMS_LOB調(diào)用使用其所有者的權(quán)限。
它不支持BFILE的并發(fā)控制機(jī)制。
你必須控制LOB的LOCK,DBMS_LOB不會(huì)隱式的LOCK LOB所在的ROW。
DBMS_LOB.LOBMAXSIZE = 4G
包含兩類操作
1)APPEND、COPY, EARSE,TRIM,WRITE,FILECLOSE,FILECLOSEALL,FILEOPEN,LOADFROMFILE
2)COMPARE,FILEGETNAME.INSTR,GETLENGTH,READ,SUBSTR,FILEEXISTS,FILEISOPEN
DBMS_LOB的任何參數(shù)為NULL,則返回值為NULL.
假如目標(biāo)LOB/BFILE=NULL,將觸發(fā)異常。
BLOB/BFILE的OFFSET以BYTE為單位,CLOB/NCLOB以字符為單位。且不能為負(fù)值,否則會(huì)觸發(fā)異常。缺省OFFSET為1。
參數(shù)不能為負(fù)值。
PROCEDURE APPEND(DEST_LOB, SRC_LOB);
把一個(gè)LOB加到另一個(gè)LOB中。
FUNCTION COMPARE(L1, L2, AMOUNT, OFFSET1,OFFSET2)
=0 ,相同
=-1,第一個(gè)小
=1,第一個(gè)大
12、系統(tǒng)治理方面的問(wèn)題
EXPORT/IMPORT支持LIBRARY和DIRECTORY,支持LOB。
IMPORT轉(zhuǎn)換EXPORT文件中的CLOB到當(dāng)前缺省的字符集。NCLOB轉(zhuǎn)換到當(dāng)前Nationanl字符集。BLOB不轉(zhuǎn)換。
BFILE不能EXP/IMP。只有BFILE的名字和DIRECTORY被EXPORT出來(lái)。
結(jié)束