Oracle嵌套表存储格式浅析

  Oracle嵌套表很少用,下面来研究下其如何存储的。用一个例子,一个用户对应对个部门。

SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE    11.2.0.1.0      Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production

SQL> create type t_dept as object(

      dept_id number,
      dept_name varchar2(20)
    )
    /
SQL> create type t_dept_arry as varray(100) of t_dept
    /
SQL> create table t_user(
     user_id number,
     user_name varchar2(10),
     depts t_dept_arry
   )
   /
SQL> insert into t_user values(1,‘张三‘,t_dept_arry(t_dept(100,‘开发一组‘),t_dept(200,‘开发二组‘)));
SQL> insert into t_user values(2,‘李四‘,t_dept_arry(t_dept(300,‘设计一组‘),t_dept(400,‘设计二组‘)));

SQL> commit;

--要想遍历用户的所有部门信息,需要用table这种特殊的形式

SQL> select user_id,user_name,d.dept_id,d.dept_name from t_user u,table(u.depts) d;
   USER_ID USER_NAME     DEPT_ID DEPT_NAME
---------- ---------- ---------- --------------------
         1 张三              100 开发一组
         1 张三              200 开发二组
         2 李四              300 设计一组
         2 李四              400 设计二组
dump block看看:         
block_row_dump:
tab 0, row 0, @0x3f47
tl: 81 fb: --H-FL-- lb: 0x1  cc: 3
col  0: [ 2]  c1 02
col  1: [ 4]  d5 c5 c8 fd
col  2: [69]
 00 01 00 00 00 00 00 01 00 00 00 0a e4 23 00 37 09 00 00 00 00 00 00 27 00
 00 00 00 00 01 88 01 27 01 01 00 02 0f 84 01 0f 02 c2 02 08 bf aa b7 a2 d2
 bb d7 e9 0f 84 01 0f 02 c2 03 08 bf aa b7 a2 b6 fe d7 e9
tab 0, row 1, @0x3ef6
tl: 81 fb: --H-FL-- lb: 0x1  cc: 3
col  0: [ 2]  c1 03
col  1: [ 4]  c0 ee cb c4
col  2: [69]
 00 01 00 00 00 00 00 01 00 00 00 0a e4 24 00 37 09 00 00 00 00 00 00 27 00
 00 00 00 00 01 88 01 27 01 01 00 02 0f 84 01 0f 02 c2 04 08 c9 e8 bc c6 d2
 bb d7 e9 0f 84 01 0f 02 c2 05 08 c9 e8 bc c6 b6 fe d7 e9
end_of_block_dump

insert into t_user values(3,‘王五‘,t_dept_arry(t_dept(500,‘家‘)));
commit;

block_row_dump:
tab 0, row 0, @0x3f5d
tl: 59 fb: --H-FL-- lb: 0x1  cc: 3
col  0: [ 2]  c1 04
col  1: [ 4]  cd f5 ce e5
col  2: [47]
 00 01 00 00 00 00 00 01 00 00 00 0a e4 49 00 21 09 00 00 00 00 00 00 11 00
 00 00 00 00 01 88 01 11 01 01 00 01 09 84 01 09 02 c2 06 02 bc d2
end_of_block_dump
--看了上面dump的结果,一头雾水,不知道是怎么存的,不过在user_objects中找到线索,有个lob字段
SQL> select object_name,object_type from user_objects s;
OBJECT_NAME                    OBJECT_TYPE
------------------------------ -------------------
SYS_LOB0000082685C00003$$      LOB
T_USER                         TABLE
T_DEPT_ARRY                    TYPE
T_DEPT                         TYPE

SQL> select column_name, segment_name, index_name
  from user_lobs s
 where s.table_name = ‘T_USER‘;
COLUMN_NAM SEGMENT_NAME                   INDEX_NAME
---------- ------------------------------ ------------------------------

DEPTS      SYS_LOB0000082685C00003$$      SYS_IL0000082685C00003$$

--再测试下跟普通的clob有什么区别

drop table test purge;
create table test
(
  id number,
  t_clob clob
);
insert into test values(1,‘开发一组开发二组‘);
insert into test values(1,‘设计一组设计二组‘);
insert into test values(1,‘家‘);

commit;

tab 0, row 0, @0x3f5d
tl: 59 fb: --H-FL-- lb: 0x1  cc: 2
col  0: [ 2]  c1 02
col  1: [52]
 00 54 00 01 02 0c 80 00 00 02 00 00 00 01 00 00 00 0a e4 4a 00 20 09 00 00
 00 00 00 00 10 00 00 00 00 00 01 5f 00 53 d1 4e 00 7e c4 5f 00 53 d1 4e 8c
 7e c4
LOB
Locator:
  Length:        84(52)
  Version:        1
  Byte Length:    2
  LobID: 00.00.00.01.00.00.00.0a.e4.4a
  Flags[ 0x02 0x0c 0x80 0x00 ]:
    Type: CLOB 
    Storage: BasicFile
    Enable Storage in Row 
    Characterset Format: IMPLICIT
    Partitioned Table: No
    Options: VaringWidthReadWrite 
  Inode: 
    Size:     32
    Flag:     0x09 [ Valid DataInRow ]
    Future:   0x00 (should be ‘0x00‘)
    Blocks:   0
    Bytes:    16
    Version:  00000.0000000001
    Inline data[16]
Dump of memory from 0x00002AE680C155EC to 0x00002AE680C155FC
2AE680C155E0                            D153005F              [_.S.]
2AE680C155F0 C47E004E D153005F C47E8C4E           [N.~._.S.N.~.]    
tab 0, row 1, @0x3f22
tl: 59 fb: --H-FL-- lb: 0x1  cc: 2
col  0: [ 2]  c1 02
col  1: [52]
 00 54 00 01 02 0c 80 00 00 02 00 00 00 01 00 00 00 0a e4 4b 00 20 09 00 00
 00 00 00 00 10 00 00 00 00 00 01 8b be 8b a1 4e 00 7e c4 8b be 8b a1 4e 8c
 7e c4
LOB
Locator:
  Length:        84(52)
  Version:        1
  Byte Length:    2
  LobID: 00.00.00.01.00.00.00.0a.e4.4b
  Flags[ 0x02 0x0c 0x80 0x00 ]:
    Type: CLOB 
    Storage: BasicFile
    Enable Storage in Row 
    Characterset Format: IMPLICIT
    Partitioned Table: No
    Options: VaringWidthReadWrite 
  Inode: 
    Size:     32
    Flag:     0x09 [ Valid DataInRow ]
    Future:   0x00 (should be ‘0x00‘)
    Blocks:   0
    Bytes:    16
    Version:  00000.0000000001
    Inline data[16]
Dump of memory from 0x00002AE680C155B1 to 0x00002AE680C155C1
2AE680C155B0 8BBE8B01 7E004EA1 8BBE8BC4 7E8C4EA1  [.....N.~.....N.~]
2AE680C155C0 02012CC4                             [.,..]            
tab 0, row 2, @0x3ef5
tl: 45 fb: --H-FL-- lb: 0x1  cc: 2
col  0: [ 2]  c1 02
col  1: [38]
 00 54 00 01 02 0c 80 00 00 02 00 00 00 01 00 00 00 0a e4 4c 00 12 09 00 00
 00 00 00 00 02 00 00 00 00 00 01 5b b6
LOB
Locator:
  Length:        84(38)
  Version:        1
  Byte Length:    2
  LobID: 00.00.00.01.00.00.00.0a.e4.4c
  Flags[ 0x02 0x0c 0x80 0x00 ]:
    Type: CLOB 
    Storage: BasicFile
    Enable Storage in Row 
    Characterset Format: IMPLICIT
    Partitioned Table: No
    Options: VaringWidthReadWrite 
  Inode: 
    Size:     18
    Flag:     0x09 [ Valid DataInRow ]
    Future:   0x00 (should be ‘0x00‘)
    Blocks:   0
    Bytes:    2
    Version:  00000.0000000001
    Inline data[2]


 选取两次的dump的内容,不过还是不能确定两者是否等价:

 00 01 00 00 00 00 00 01 00 00 00 0a e4 49 00 21 09 00 00 00 00 00 00 11 00
 00 00 00 00 01 88 01 11 01 01 00 01 09 84 01 09 02 c2 06 02 bc d2

 00 54 00 01 02 0c 80 00 00 02 00 00 00 01 00 00 00 0a e4 4c 00 12 09 00 00
 00 00 00 00 02 00 00 00 00 00 01 5b b6


   总结:嵌套是通过lob在存储嵌套的内容的,TOM说作为一种存储机制,他更倾向于创建父子表,可以再创建一个视图,看上去像一个真正的嵌套表一样,嵌套表适合于编程构造。

Oracle嵌套表存储格式浅析

上一篇:oracle建用户


下一篇:oracle buffer cache的基本原理