这篇博客来讨论一下12c中的CLOB数据类型。
在应用开发阶段设计表字段类型的时候,文字内容在4000字符以内通常使用varchar2类型,但是从12c开始通过下面的语句开启扩展模式将varchar2扩展到32676字符。在是否选择大对象CLOB类型时多了一个选择。
alter system set max_string_size=EXTENDED scope=both;
CLOB:用于存储字符文档的字符型大型对象,如文本文件、日志文件、XML文件等。
NCLOB:国家字符集大型对象,使用国家字符集格式存储数据,支持可变长度字符串。
内部大对象数据类型使用LOB块存储数据。LOB块是大对象数据中最小的存储单位,它由一个或多个数据块组成。LOB定位器存储在含有大对象列的行中。LOB定位器指向LOB索引。LOB索引存储了LOB块的位置信息。查询表时数据库会使用LOB定位器和相关LOB索引,查找LOB块的位置。
在Oracle10g中CLOB的基础结构为BasicFiles,Oracle11g之后推出了新特性SecureFiles,但是需要手工开启,Oracle12c开始SecureFiles作为了首选基础结构。
SecureFiles的出现大大提高了CLOB的“格调”,从一个死板的文字堆砌类型变成了可压缩,可加密,可去重的“人性”模式。
SecureFiles压缩功能类似于zip压缩文本文件一样,可以省去很多空间。当数据库中又大量CLOB字段时会大幅度节省磁盘空间。去重功能类似于云盘存储,只保留一份文件,其它同名文件使用指针引用那一份文件,不再保留多份。从某种意义上讲也算是一种压缩。加密功能以透明方式加密大对象数据,和加密其它类型的数据一样。
使用SecureFiles有一个前提条件就是表空间需要自动管理(ASSM)。在12c中创建表空间默认采用的就是ASSM,不需要手工指定。
create tablespace lob_data
datafile '/u01/app/oracle/oradata/cdb/pdb1/lob_data01.dbf' size 100m
uniform size 1m;
select tablespace_name,segment_space_management from dba_tablespaces where tablespace_name='LOB_DATA';
TABLESPACE_NAME SEGMEN
------------------------------ ------
LOB_DATA AUTO
如果默认类型不是ASSM可以在创建表空间语句中指定segment space management auto字句。
下面来创建一个含有大对象的表library,CLOB字段为article保存在lob_data表空间。创建后会默认支持SecureFiles类型。
create table library (id number,article clob) tablespace baymax
lob(article) store as (tablespace lob_data);
如果是Oracle11g的话需要明确指定SecureFiles的方式创建,并且设置参数:
alter system set db_securefile=permitted;
create table library11g(id number, article clob) tablespace users
lob(doc) store as securefile(tablespace LOB_TBS compress high deduplicate);
通过下面的语句可以查看lob对象是否为SecureFiles
col table_name for a15
col segment_name for a30
col index_name for a30
set line 100
select table_name,segment_name,index_name,securefile,in_row from user_lobs;
TABLE_NAME SEGMENT_NAME INDEX_NAME SEC IN_
--------------- ------------------------------ ------------------------------ --- ---
LIBRARY SYS_LOB0000092836C00002$$ SYS_IL0000092836C00002$$ YES YES
大对象创建LOB段采用延时加载技术,添加一条记录后才能看到段信息
insert into library values(1,'clob text');
commit;
通过下面的语句可以查看LOB段的类型为securefile。12c默认的LOB类型就是SecureFiles,11g则需要在创建表是添加store as securefile字句
select segment_name,segment_type,segment_subtype,bytes/1024/1024 mb
from user_segments where segment_name in ('LIBRARY','SYS_IL0000092836C00002$$','SYS_LOB0000092836C00002$$');
SEGMENT_NAME SEGMENT_TYPE SEGMENT_SU MB
------------------------------ ------------------ ---------- ----------
LIBRARY TABLE ASSM .0625
SYS_IL0000092836C00002$$ LOBINDEX ASSM 1
SYS_LOB0000092836C00002$$ LOBSEGMENT SECUREFILE 1
通过下面的语句可以看出表和LOB字段位于不同的表空间,这么做的好处是便于维护和管理LOB段快速增长的状态。
col table_name for a10
col tablespace_name for a15
col col_name for a15
select table_name,tablespace_name,'N/A' col_name from user_tables where table_name='LIBRARY'
union
select table_name,tablespace_name,column_name from user_lobs where table_name='LIBRARY';
TABLE_NAME TABLESPACE_NAME COL_NAME
---------- --------------- ---------------
LIBRARY BAYMAX N/A
LIBRARY LOB_DATA ARTICLE
SecureFiles比BasciFiles先进的地方还包括对LOB段的压缩和去重。如果在创建表时没有设计这些功能,可以使用下面的语句添加。
alter table library modify lob(article) (compress high deduplicate lob);
注意deduplication字段中启用去重为显示LOB,不启用去重显示NO
select table_name,tablespace_name,column_name,compression,deduplication from user_lobs;
TABLE_NAME TABLESPACE COLUMN_NAM COMPRE DEDUPLICATION
---------- ---------- ---------- ------ ---------------
LIBRARY LOB_DATA ARTICLE HIGH LOB
如果要取消压缩、取消去重功能卡参考官方文档
alter table library modify lob(article) (nocompress keep_duplicates);
去重功能在表中包含大量重复内容的LOB字段时效果显著,重复内容越多效果越明显。