日期:2014-05-16  浏览次数:20506 次

Oracle 数据类型及存储方式(四)LOB类型

第四部分 LOB类型
§ 4.1 LOB类型
4.1.1 LOB类型分类
CLOB:字符LOB.用于存储大量的文本信息.采用默认字符集存储
NCLOB:用于存储字符LOB,采用数据库的国家字符集来存储字符.而不是数据库的默认字符集.
BLOB:二进制LOB,存储二进大量的二进制信息.存储时不会进行字符集转换.
CLOB和BLOG在ORACLE 10G中可存储8TB字节.
BFILE:二进制文件LOB,只是一个文件指针.具体的文件存储在操作系统中.

4.1.2 LOB类型存储方式

我们把CLOB,NCLOB,BLOB存储在数据库的内部称为内部LOB.这些存储方式都相似,所以可以一起进行讨论.

SQL> create table test_lob (id int primary key,remark clob);

Table created

对于LOB列的创建有非常多的选项.可以查ORACLE文档.
最简单的就是使用dbms_metadata来获得它的完整的脚本.
select dbms_metadata.get_ddl('TABLE','TEST_LOB') from dual;

得到如下结果
CREATE TABLE "YUAN"."TEST_LOB"
?? ( "ID" NUMBER(*,0),
"REMARK" CLOB,
PRIMARY KEY ("ID")
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "USERS" ENABLE
?? ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "USERS"
LOB ("REMARK") STORE AS (
TABLESPACE "USERS" ENABLE STORAGE IN ROW CHUNK 8192 PCTVERSION 10
NOCACHE LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT))

LOB列的定义可以有以下属性.
存储的表空间,本例为USER.也就是说可以为LOB单独指定表空间.
ENABLE STORAGE IN ROW 默认的一个属性
CHUNK 属性
PCTVERSION 属性
NOCACHE 属性.
一个完整的STORAGE语句.

可见,LOB类型之前介绍的数据类型相比要复杂得多了.
当我们创建了一个带的LOB列的表后,我们可以从USER_SEGMENTS查到,数据库增加了几个段对象.
SQL> select segment_name,segment_type from user_segments;

SEGMENT_NAME????????????????????? SEGMENT_TYPE
--------------------------------- ------------------
BIN$nZwCJWDmQM+ygfB1U8tcIw==$0??? TABLE
BIN$0jfW0nNQR/2JEQmbAmfcRQ==$0??? TABLE
TEST_TIMESTAMP??????????????????? TABLE
TEST_TIMESTAMP2?????????????????? TABLE
TEST_TIMESTAMPWZ????????????????? TABLE
TEST_TIMELTZ????????????????????? TABLE
TEST_INTERVARYM?????????????????? TABLE
TEST_INTERVALYM2????????????????? TABLE
TEST_INTERVALDS?????????????????? TABLE
TEST_LOB????????????????????????? TABLE
SYS_LOB0000043762C00002$$???????? LOBSEGMENT
SYS_IL0000043762C00002$$????????? LOBINDEX
SYS_C004324?????????????????????? INDEX

后面四个段空间对象.新增了四个物理段.普通表只会新增一个或两个段对象.类型为TABLE和INDEX.
而LOB列则额外新增了两个段对象,类型为LOBSEGMENT和LOBINDEX.
SYS_C004324是一个索引段,因为我们有一列为主键.
作为普通字段,数据就存放在表段中.索引就放在索引段中.
而对于LOB数据,数据并不是存在表段中,而是存放在LOBSEGMENT段中.(有些情况下是存放在表test_lob中的.后面会讲)
LOBINDEX用于指向LOB段,找出其中的某一部分.
所以存储在表中的LOB存储的是一个地址,或者说是一个指针,也可以说是一个LOB定位器(LOB locator).
存储在LOBindex中的应该是每一个LOB行的地址.数据是具体存储在LOBSEGMENT中的.
我们先从TEST_LOB的LOB列中找到一个地址,然后在LOBINDEX中来查找这些字节存储在哪里.然后再访问LOBSEGMENT.由此我们可以 把lobindex和lobsegment想成是一个主/细表的关系.


实际上lob列中存的是一个地址段.然后在lobindex找到所有的地址段.然后在lobSegment中把所有地址段的值都读取了来

4.1.3 LOB类型存储参数介绍
在此,我们已经基本了解了LOB是怎么存储的.我们也从脚本中看到了LOB类型的参数.现在我们就来了解这些参数
1. LOB表空间
LOB ("REMARK") STORE AS (
TABLESPACE "USERS"
在test_lob表中的create语句中包含上面的语句.这里指定的表空间指的是存储lobindex 和lobsegment的表空间.也就是说,存放lob数据与LOB列所在的表是可以在不同的表空间的.
数据表和LOB存放在不同的表空间.
为什么LOB数据会放在不同的表空间呢?这主要还是管理和性能的问题.
LOB数据类型代表了非常巨大的容量.在ORACLE 10G之前,LOB列可以存放4GB字节的数据.在ORACLE 10G 中LOB类型可以存放8TB字节的数据.这是非常庞大的数据.
所以就有必要为LOB数据使用一个单独的表空间,对于备份和恢复以及空间管理.你甚至可以让LOB数据使用另外一个区段大小,而不是普通表数据所用的区段 大小.
另外从I/O性能的角度考虑.LOB是不在缓冲区缓存中进行缓存.因此每个LOB的读写,都会产生物理I/O.正因为如此,如果我们很清楚在实际的用户访 问中,有些对象会比大部分其它对象需要花费更多的物理I/O,那么就需要把这些对象分离到其它的磁盘.
另外,lobindex 和lobsegment是在同一个表空间中的.不可以把lobindex和lobsegment放在不同的表空间中.在oracle 8i之前版本,允许将lobindex和lobsegment放在不同的表空间中.
2. IN ROW 语句
L