1、 0、LARGE OBJECT Oracle8 中有 4种 LOB - BLOB:Binary Large Object - CLOB:Character Large Object - NCLOB:固定长度的多字节 Character Large Object - BFILE:DB 外部的二进制文件 它们分为两类: 内部 LOB:存放在 DB内部,包括 BLOB,CLOB,BCLOB 外部文件:存放在 DB外面,就是 BFILE 要注重的是 ORACLE8不自动转换这些类型的数据。 1、LONG 和 LOB的比较 LONG/LONG RAW LOB - 表中只能由一个列 可以有多列 最大 2G
2、 最大 4G SELECT 返回值 SELECT 返回指针 存放在 DB内 可以在 DB的内或者外 不支持 OBJECT类型 支持 顺序存取 随机存取 - NCLOB 不支持 OBJECT类型 LOB 小于 4000字节时是内部存放 2、LOB 解析 LOB 有两个不同的部分 - LOB 值:LOB 代表的数据 - LOB 指针:LOB 存放数据的位置 LOB 列内部不存放数据,而是 LOB值的位置。当创建内部 LOB时,值存放在 LOB SEGMENT中,指向 OUT-OF-LIN数据的指针放在列中。对外部 LOB,只在列中存放位置。 3、内部 LOB 就是存放在 DB内部的 LOB,包括
3、BLOB,CLOB,NCLOB。它们可以是 用户自定义的类型中的属性 表中某列 SQL 变量 程序 host变量 PL/SQL 中的变量、参数、返回值 内部 LOB可以使用 ORACLE的并发机制、REDO LOG、RECOVERY 机制。 BLOB 被 ORACLE8解释为二进制位流,类似 LONG RAW。 CLOB 解释为单字节字符流 NCLOB 是固定的多字节字符流,基于 DB NATIONAL字符集的字节长度。 例子: CREATE TYPE picture_typ AS OBJECT (image BLOB); CREATE TABLE person_tab ( pname VAR
4、CHAR2(20), RESUME CLOB, picture picture_typ ); 上面的语句完成后,数据将存放在 5个物理 SEGMENT中。 - TABLE person_tab 在缺省 TABLESPACE, - RESUME 存放的 LOB SEGMENT - PICTURE 存放的 LOB SEGMENT - 标示 RESUME存放位置的 LOB INDEX SEGMENT - 标示 PICTURE存放位置的 LOB INDEX SEGMENT LOB INDEX 是隐式创建的。 当 INSERT或者 OBJECT CACHE中的 OBJECT刷新到 SERVER时,LOB
5、 生成。可以使用DBMS_LOB包和 OCI来处理 LOB。当 ROW删除时,相应的内部 LOB也会删除。UPDATE 必须处理整个 LOB值,不能 UPDATE其中的一部分。 4、内部 LOB的存储参数 具体语法可以参见 ORACLE文档, LOB ( lob 项,.) STORE AS lob_segment_name CHUNK integer PCTVERSION integer CACHE NOCACHE LOGGING/NOLOGGING TABLESPACE tablespace_name STORAGE storage 子句 INDEX INDEX 字句 lob_segment
6、_name:缺省式 LOB$n CHUNK:连续分配在一起的 BLOCK数目,存放连续的 LOB数据。这些 CHUNK的数据存放在 LOB INDEX里面,使用内部 LOB标示和 LOB值作为键。 PCTVERSION:LOB 一致读需要的系统空间。一旦 LOB申请超过 PCTVERSION的值,ORACLE就会收旧的空间并 REUSE之。 CACHE:使用 SGA区的 DB BUFFER CACHE处理 LOB的 READ/WRITE。 NOCACHE LOGGING:不使用 SGA区的 BUFFER,数据的改变纪录到 REDO LOG。 存取 LOB比较频繁时,使用 CACHE 存取 LO
7、B不频繁时,使用 NOCACHE NOCACHE NOLOGGING:不使用 SGA区的 BUFFER和 REDO LOG INDEX 子句 INDEX lob_index_segtment_name INITTRANS integer MAXTRANS integer TABLESPACE tablespace_name STORAGE storage 子句 假如没有设置 LOB存储参数和 INDEX STROAGE,则采用如下缺省值 CHUNK=1 DB_BLOCK PCTVERSION=10 NOCACHE NOLOGGING 例子: CREATE TABLE APARTMENTS (
8、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、内部 LOB的并发 LOB 的读一致和其他 ORACLE类型一样,但是它是在 CHUNK级别上作 VERSION的。 6、外部 LOB ORACLE8 答应定义 BFILE类型
9、,可以把外部文件和 BFILE对象连接起来,同时能提供BFILE的安全机制。 BFILE 对处理不需要 transaction控制的 OS文件很有用处。 对 BFILE的处理需要 DBMS_LOB或者 OCI。 BFILE 必须是 READ-ONLY的,文件应该放在 ORACLE能存取的地方。假如删除 BFILE对象,外部文件并不删除。 例子: CREATE TABLE home_page( EMPLOYEE REF EMPLOYEE_TYP, LAST_UPDATE DATE, HOMEPAGE BFILE); CREATE TYPE personal_info_typ AS OBJECT
10、( EMPLOYEE REF employee_typ, PICTURE BFILE, THUMBPRINT BFILE, REINAPRINT BFILE ); 其实在 BFILE对应的列或者属性中存放的是 BFILE的位置,即是物理文件的位置。 读 BFILE不通过 SGA. 7、BFILE 的安全 ORACLE8 提供安全机制。文件必须和 DB在一台机器上,读取不存在文件的 timeout由os决定。可以和内部 LOB的读取方法一致,但是必须注重:文件的权限、文件系统空间限制、其他对文件的维护、OS 答应的最大文件大小。 ORACLE8 不对 BFILE采取 TRANSACTION的支持
11、,ORACLE 的 BACKUO和 RECOVERY也不支持 BFILE。 8、目录 DirectorY 这是 ORACLE为了治理 BFILE引入的新元素,它指定 SERVER文件系统的目录,可以把文件系统的目录抽象为数据库对象,更具有灵活性。 DIRECTORY 由 DBA建立,系统用户拥有,通过 GRANT/REVOKE来确定哪些用户有权限。 CREATE OR REPLACE DIRECTORY 目录名 AS 路径名 DROP DIRECTORY 目录名 存取 BFILE在如下情况时候产生异常: -用户没有操作 DIRECTORY的权限 -DIRECTORY 所对应的物理目录不存在,或
12、者没有存取该目录的权限。 -文件不存在 文件和权限的检查是在文件存取时候检查的,创建时候并不报错。 不支持逻辑路径 系统新增加了 CREATE ANY DIRECTORY和 DROP ANY DIRECTORY。对 DIRECTORY授权只有 READ。 对 CREATE DIRECTORY和 GRANT READ ON DIRECTORY是可以 AUDIT的。 8、DIRECTORY 建立的原则 DIRECTORY 不要和 DB DATAFILE在相同的目录下。 要有选择的赋予 CREATE ANY DIRECTORY和 DROP ANY DIRECTORY ROLE。 在建立之前要在 OS
13、级别上设置权限。 假如移植 DB到其他机器,需要注重 DIRECTORY的路径是否改变。 9、治理 LOB ORACLE 通类似文件操作一样的接口:DBMS_LOB, OCI8。同时还有 SQL语句的一些支持。治理 LOB的一般方法: 1)CREATE/POPULATE 包含 LOB的 TABLE, 2)在程序中 DECLARE AND INITIALIZE LOB Locator 3)用 SELECT FOR UPDATE 锁定包含 LOB的 ROW, 4)用 DBMS_LOB或者 OCI维护相关 LOB值 5)COMMIT 治理 BFILE的一般方法 1)建立 OS目录,授予 ORACLE
14、 用户 READ的权限 2)把文件放到该目录 3)建立包含 BFILE的 TABLE 4)建立 DIRECTORY,用 GRANT授权 5)在 TABLE中 INSERT与文件相关的值 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。当把一个 LOB赋给另一个时
15、,其实是新建了一个 LOB。这些操作不需要 SELECT FOR UPDATE。只有在更新 LOB的其中一部分的时候才需要先 LOCK。 ORACLE8 不会自动转换 CLOB和 BLOB。 最好的办法是 OCILobWrite,以为它使用 ORACLE的流机制,最快、使用更好的空间和REDO。 删除 LOB的方法 DELETE TRUNCATE TABLE DROP TABLE . 删除后注重在 OS级别上删除相关文件。 假如只是要去掉 LOB的 Locator,可以用 NULL或者空字符串来 UPDATE。 11、DBMS_LOB 包 DBMS_LOB 包用 SYS用户提交 DBMSLOB
16、.SQL和 PRVTLOB.PLB脚本。它们包含在CATPROC.SQL中。用户要授权才能使用它。匿名 BLOCK中的 DBMS_LOB例程使用当前用户的权限。STORED PROCEDURE 中的 DBMS_LOB调用使用其所有者的权限。 它不支持 BFILE的并发控制机制。 你必须控制 LOB的 LOCK,DBMS_LOB 不会隐式的 LOCK LOB所在的 ROW。 DBMS_LOB.LOBMAXSIZE = 4G 包含两类操作 1)APPEND、COPY, EARSE,TRIM,WRITE,FILECLOSE,FILECLOSEALL,FILEOPEN,LOADFROMFILE 2)C
17、OMPARE,FILEGETNAME.INSTR,GETLENGTH,READ,SUBSTR,FILEEXISTS,FILEISOPEN DBMS_LOB 的任何参数为 NULL,则返回值为 NULL. 假如目标 LOB/BFILE=NULL,将触发异常。 BLOB/BFILE 的 OFFSET以 BYTE为单位,CLOB/NCLOB 以字符为单位。且不能为负值,否则会触发异常。缺省 OFFSET为 1。 参数不能为负值。 PROCEDURE APPEND(DEST_LOB, SRC_LOB); 把一个 LOB加到另一个 LOB中。 FUNCTION COMPARE(L1, L2, AMOUNT, OFFSET1,OFFSET2) =0 ,相同 =-1,第一个小 =1,第一个大 12、系统治理方面的问题 EXPORT/IMPORT 支持 LIBRARY和 DIRECTORY,支持 LOB。 IMPORT 转换 EXPORT文件中的 CLOB到当前缺省的字符集。NCLOB 转换到当前Nationanl字符集。BLOB 不转换。 BFILE 不能 EXP/IMP。只有 BFILE的名字和 DIRECTORY被 EXPORT出来。结束