CLOB 컬럼은 과거 LONG 타입과는 다르게 테이블 당 여러 개로 선언될 수 있으며 STORATE IN ROW 옵션에 따라 다른 데이터와 같이 테이블 세그먼트에, 또는 CLOB 전용 세그먼트에 저장될 수 있다. 이를 증명하기 위해 아래와 같은 테스트 데이터를 사용한다.
clob 테스트를 위한 데이터
create table tc( c1 char(24), clob1 clob);
insert into tc values ('1111111111111', ‘a……….a');<-- ‘a’ : 200개
insert into tc values ('2222222222222', ‘b……….b’);<-- ‘b’ : 20,000 개
commit;
tc 테이블은 한 컬럼은 char 타입, 다른 컬럼은 clob 타입으로 구성된 테이블이다. 그리고 STORAGE IN ROW 옵션에 따른 저장 구조를 확인하기 위해 clob1의 한 로우는 4000 바이트보다 작은 200 바이트로 나머지 로우는 4000 바이트 이상인 20,000 바이트로 저장되어 있다. 데이터베이스에 저장되는 블록의 저장 구조는 다음과 같다.
ENABLE STORATE IN ROW 옵션은 주는 경우 CLOB1 컬럼이 4000 바이트 기준으로 작은 경우에는 테이블 세그먼트에, 4000 바이트 보다 큰 경우에는 별도의 LOB 세그먼트에 저장된다.
위 그림에서 윗 부분이 스토리지 옵션이 ENABLE STORATE IN ROW 으로서 C1 컬럼 값이 '1111111111111'인 경우는 4000바이트 보다 작기 때문에 테이블 세그먼트에 C1 컬럼 값이 '2222222222222' 인 경우는 4000바이트보다 크기 때문에 LOB 세그먼트에 저장되고 해당 LOB CHUNK(블록 대신 청크로 표현)를 가리키는 LOB LOCATOR가 테이블 세그먼트에 저장된다.
DISABLE STORATE IN ROW 옵션을 주는 경우에는 CLOB1의 크기에 관계없이 모두 별도의 LOB 세그먼트에 저장되고 해당 청크를 가리키는 LOB LOCATOR만 테이블 세그먼트에 저장된다.
오라클이 실제 저장하는 블록의 구조를 알아보기 위해서 아래와 같은 sql을 이용해서 해당 테이블 세그먼트의 블록을 덤프해서 볼 수 있다. 이 때 clob1 은 enable storate in row 옵션으로 생성된 경우이다.
select rowid , dbms_rowid.rowid_relative_fno(rowid) as relative_fno , dbms_rowid.rowid_block_number(rowid) as blkno from tc where trim(c1) = '1111111111111'
덤프한 결과를 확인 해 보면 clob1 컬럼은 'aaaa...' , 'bbbbb...' 값이 아스키 코드로 되어 있어도 저장시에는 유니코드로 저장이 된다. c1 의 값이 '1111111111111'인 경우 '61006100...'으로 저장되어 있다. 오라클의 캐릭터 셋이 가변인 경우에는 데이터 타입이 NCLOB이 아니더라도 CLOB 타입은 유니코드로 저장된다.
Block header dump: 0x01000275 Object id on Block? Y seg/obj: 0x128a6 csc: 0x00.2d6a22 itc: 2 flg: E typ: 1 - DATA brn: 0 bdba: 0x1000270 ver: 0x01 opc: 0 inc: 0 exflg: 0
데이터 덤프를 이용하여 TC 테이블을 덤프한 경우 파일의 구조는 clob의 스토리지 옵션(enable, disable)에 관계없이 모두 한 로우에 나열하여 파일에 저장한다. c1이 '2222222222222' 인 경우 다시 말해서 별도의 LOB 세그먼트에 저장되어 있어도 덤프시에는 한 로우에 붙여서 덤프하는 것을 확인할 수 있다.