根据一些经验,发现数据库中有LOB(large object)类型字段,往往会伴随一些数据库的问题出现。有些人对LOB字段的用法存在着误解。下面简单说说LOB 类型。
先说Oracle支持的4中类型

简单的概括就是 CLOB 和 NCLOB 保存文本信息,BLOB 保存二进制信息。
存储结构:从Oracle 11g 开始,引入了SecureFiles 新的LOB 架构11G 之前叫BasicFiles.在Oracle11G中如果不特别指定,默认是会创建成BasicFiles LOB.但是在Oracle12C之后,LOB列在ASSM管理的表空间.默认都会是SecureFiles .
SecureFiles的好处是:
Oracle官方文档已经说明,BasicFiles在后续版本将不能使用。
管理更加简单CHUNK,FREELISTS,FREELISTGROUPS等参数不在支持。
SecureFiles 支持加密,压缩和去重.
强烈建议使用SecureFiles 而不是BasicFiles.
创建SecureFile LOB
CREATE TABLE T_LOB (ID INT PRIMARY KEY, TXT CLOB);
查看是否为SecureFiles

必须使用TORE AS SECUREFILE 字句创建表:
CREATE TABLE T_LOB_SECURE (ID INT PRIMARY KEY, TXT CLOB) LOB(TXT) STORE AS SECUREFILE;

看看具体两者表结构的区别:
select dbms_metadata.get_ddl('TABLE', 'T_LOB_SECURE') FROM DUAL;
CREATE TABLE "SCOTT"."T_LOB_SECURE"
( "ID" NUMBER(*,0),
"TXT" CLOB,
PRIMARY KEY ("ID")
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255
STORAGE(INITIAL 1048576 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "TBS_TS1" ENABLE
) SEGMENT CREATION IMMEDIATE
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
NOCOMPRESS LOGGING
STORAGE(INITIAL 1048576 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "TBS_TS1"
LOB ("TXT") STORE AS SECUREFILE (
TABLESPACE "TBS_TS1" ENABLE STORAGE IN ROW CHUNK 8192
NOCACHE LOGGING NOCOMPRESS KEEP_DUPLICATES
STORAGE(INITIAL 1048576 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT))
select dbms_metadata.get_ddl('TABLE', 'T_LOB') FROM DUAL;
CREATE TABLE "SCOTT"."T_LOB"
( "ID" NUMBER(*,0),
"TXT" CLOB,
PRIMARY KEY ("ID")
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255
STORAGE(INITIAL 1048576 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "TBS_TS1" ENABLE
) SEGMENT CREATION IMMEDIATE
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
NOCOMPRESS LOGGING
STORAGE(INITIAL 1048576 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "TBS_TS1"
LOB ("TXT") STORE AS BASICFILE (
TABLESPACE "TBS_TS1" ENABLE STORAGE IN ROW CHUNK 8192 RETENTION
NOCACHE LOGGING
STORAGE(INITIAL 1048576 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT))
比较发现SECUREFILE 和 BASICFILE 大部分属性是一样。
LOB 如何存储数据
当创建 T_LOB_SECURE 表后,数据库会生成下面4个段。
SEGMENT_NAME SEGMENT_TYPE
T_LOB_SECURE TABLE
SYS_IL0000100726C00002$$ LOBINDEX
SYS_C0012385 INDEX
SYS_LOB0000100726C00002$$ LOBSEGMENT
TABLE 是表,INDEX 是主键创建对应的索引约束.LOBINDEX 和LOBSEGMENT 是用来存储LOB 数据.实际上LOB 数据是存储在LOBSEGMENT中.LOBINDEX 是用于从LOB 中找出数据的某些片段.当创建lob列时,存储在行中的是一个指针,也叫lob定位器.当在读取数据的时候,就需要使用到这个lob 定位器.比如当要读取600到1200字节时,oracle会使用lob定位器和LOBINDEX 找出这些字节存储在哪里,然后再访问LOBSEGMENT.相当于先通过指针定位到地址,再读取数据.LOBINDEX 提高了整个效率.
LOB表空间
根据DDL 语句定义,不管用那种方式,store 后面的 tablespace 是存储 LOBSEGMENT和LOBINDEX的表空间.
LOB ("TXT") STORE AS BASICFILE (
TABLESPACE "TBS_TS1"
LOB ("TXT") STORE AS SECUREFILE (
TABLESPACE "TBS_TS1"
LOB数据和表实际的所在的表空间可以不同:主要有两方面的考虑:
1.方便管理,数据和LOB 在不同的表空间,管理上互补干扰,还能提高备份恢复的效率。2.提高I/O性能,默认情绪下Oracle不会缓存LOB,所以每次读写操作都是物理I/O操作.表空间分开可以做存储IO能力针对性调整。
另外。LOBINDEX和LOBSEGMENT 必须在同一个表空间,无法分开。
ENABLE STORAGE IN ROW
不管用BASICFILE 还是 SECUREFILE 默认 都是ENABLE STORAGE IN ROW。这是控制LOB数据是否与表分开存储。如果是ENABLE,小于4000字节的LOB会像VARCHAR2一样寸在表本身中。这样只有大于4000字节时,才会存放到LOBSEGMENT中。默认使用这种方式,不建议进行修改。enable能提高查询效率。
CHUNK 参数
LOB数据存储在chunk(片)中,LOB 索引会指向chunk,chunk是逻辑上连续的一组数据库块,是lob的最小分配单位。我们都知道数据库存储的最小分配单元是数据库块。chunk大小必须是oracle块大小的整数倍。chunk参数只适
用于BASICFILE 。
RETENTION参数
LOB数据的读一致性和普通数据不一样。LOBSEGMENT 并不适用UNDO段来记录其修改,而是直接使用LOBSEGMENT 本身来维护多版本读。也就是说当修改一个LOB时,Oracle会分配一个新的chunk,修改的数据写入写的chunk,但是原来的chunk还会保留。也就是说LOBSEGMENT的undo信息没有存在数据库的undo段中。
以上是LOB 的一些基础知识介绍。
下一篇介绍如何回收LOB 字段空间?




