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' |
ROWID RELATIVE_FNO BLKNO ------------------- ------------------------ ---------- AAAZm9ABWAADb9rAAA 86 900971 |
alter system dump datafile 86 block 900971 |
덤프한 결과를 확인 해 보면 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 Itl Xid Uba Flag Lck Scn/Fsc 0x01 0x000a.014.000007c4 0x00c00342.0202.1d --U- 3 fsc 0x0000.002d6a28 0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000 bdba: 0x01000275 data_block_dump,data header at 0xd465264 =============== tsiz: 0x1f98 hsiz: 0x18 pbl: 0x0d465264 76543210 flag=-------- ntab=1 nrow=3 frre=-1 fsbo=0x18 fseo=0x1d1b avsp=0x1d03 tosp=0x1d03 0xe:pti[0] nrow=3 offs=0 0x12:pri[0] offs=0x1dc5 0x14:pri[1] offs=0x1d70 0x16:pri[2] offs=0x1d1b block_row_dump: tab 0, row 0, @0x1dc5 tl: 467 fb: --H-FL-- lb: 0x1 cc: 2 col 0: [24] 31 31 31 31 31 31 31 31 31 31 31 31 31 20 20 20 20 20 20 20 20 20 20 20 col 1: [436] <--- c1의 값이 '1111111111' 인 경우에는 테이블 세그먼트에 포함됨
00 54 00 01 02 0c 80 00 00 02 00 00 00 01 00 00 00 10 d0 e5 01 a0 09 00 00 00 00 00 01 90 00 00 00 00 00 01 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 00 61 LOB Locator: <--- c1의 값이 '2222222222222' 인 경우에는 외부 세그먼트의 저장 위치 Length: 84(436) Version: 1 Byte Length: 2 LobID: 00.00.00.01.00.00.00.10.d0.e5 Flags[ 0x02 0x0c 0x80 0x00 ]: Type: CLOB Storage: BasicFile Enable Storage in Row Characterset Format: IMPLICIT Partitioned Table: No Options: VaringWidthReadWrite Inode: Size: 416 Flag: 0x09 [ Valid DataInRow ] Future: 0x00 (should be '0x00') Blocks: 0 Bytes: 400 Version: 00000.0000000001 Inline data[400] Dump of memory from 0x000000000D46706C to 0x000000000D4671FC 00D467060 61006100 [.a.a] 00D467070 61006100 61006100 61006100 61006100 [.a.a.a.a.a.a.a.a] Repeat 23 times 00D4671F0 61006100 61006100 61006100 [.a.a.a.a.a.a] tab 0, row 1, @0x1d70 tl: 85 fb: --H-FL-- lb: 0x1 cc: 2 col 0: [24] 32 32 32 32 32 32 32 32 32 32 32 32 32 20 20 20 20 20 20 20 20 20 20 20 col 1: [56] 00 54 00 01 02 0c 80 00 00 02 00 00 00 01 00 00 00 10 d0 e6 00 24 05 00 00 00 00 04 1d 30 00 00 00 00 00 02 01 00 02 7d 01 00 02 7e 01 00 02 7f 01 00 02 7b 01 00 02 7c |
[expdp 시 덤프 파일의 구조]
데이터 덤프를 이용하여 TC 테이블을 덤프한 경우 파일의 구조는 clob의 스토리지 옵션(enable, disable)에 관계없이 모두 한 로우에 나열하여 파일에 저장한다. c1이 '2222222222222' 인 경우 다시 말해서 별도의 LOB 세그먼트에 저장되어 있어도 덤프시에는 한 로우에 붙여서 덤프하는 것을 확인할 수 있다.
0023500 4f52 5357 5445 003e 020c 3148 3131 3131
0023520 3131 3131 3131 3131 2020 2020 2020 2020
0023540 2020 2020 2020 2020 2020 2020 2020 2020
0023560 2020 2020 2020 2020 2020 2020 2020 2020
0023600 2020 2020 2020 2020 2020 2020 2020 2020
0023620 2020 fe20 9001 6100 6100 6100 6100 6100
0023640 6100 6100 6100 6100 6100 6100 6100 6100
*
0024440 6100 6100 6100 020c 3248 3232 3232 3232
0024460 3232 3232 3232 2020 2020 2020 2020 2020
0024500 2020 2020 2020 2020 2020 2020 2020 2020
*
0024560 fe20 4a5f 6200 6200 6200 6200 6200 6200
0024600 6200 6200 6200 6200 6200 6200 6200 6200
*
0104260 6200 6200 6200 6200 6200 6200 6200 0000
0104300 0000 0000 0000 0000 0000 0000 0000 0000 |