首页 / 数据库 / MySQL / 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 TYPESQL> 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说作为一种存储机制,他更倾向于创建父子表,可以再创建一个视图,看上去像一个真正的嵌套表一样,嵌套表适合于编程构造。在CentOS 6.4下安装Oracle 11gR2(x64) http://www.linuxidc.com/Linux/2014-02/97374.htmOracle 11gR2 在VMWare虚拟机中安装步骤 http://www.linuxidc.com/Linux/2013-09/89579p2.htmDebian 下 安装 Oracle 11g XE R2 http://www.linuxidc.com/Linux/2014-03/98881.htm更多Oracle相关信息见Oracle 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=12本文永久更新链接地址
收藏该网址