Oracle的体系结构中,关于存储结构大家应该都很熟悉了。
估计下面这张图大家都看得熟悉的不能再熟悉了。
首先老三篇的内容我们换一种玩法,如果是一个11gR2的默认数据库环境,下面的这个语句会创建几个段。
create table test_seg (id number primary key,name varchar2(30),memo clob);
这个问题问住了不少的人,而似乎我也听到了不少意料之中的答案,如果认为是1个的,就是理解创建了一个表,那就是一个段了,这个段类型是TABLE,如果认为是2个的,那就是看到了里面有一个主键,那就是对应一个索引段,如果认为是3个的,那就是看到了LOB字段,不过还差一步,LOB其实是会创建两个段,一个是LOB段,一个是LOB索引段,结构化的数据是Oracle的强项,而如果加入半结构化的数据处理,就得额外花些功夫。而如果我们在11gR2的环境中,我们耳濡目染的而一个特性,延迟段创建,存在一个数据库参数segment_deferred_creation默认为true,即开启了延迟段创建,所以上面的语句不会创建任何的段。
SQL> select segment_name,segment_type from user_segments;
而我们插入一部分的数据,我们就插入近50万数据吧。insert into test_seg select level,'obj'||level,'' from dual connect by level<500000;
这样一来,问题就回归了,是4个段,其中SYS_IL开头的段是索引段,剩下SYS_开头的两个是LOB相关的段。
select segment_name,segment_type from user_segments;
怎么去理解这个段呢。
我们还是求助于user_segments来看看。
SQL> select segment_name,extents,blocks from user_segments
可以看到段TEST_SEG存在26个区块,含有1408个数据块。这些都是概览的信息。
如果想得到更细致一些的信息呢,那就是user_extents了。我们简化一下,只是查看segment_type为TABLE的区块信息。
SQL> select segment_name,segment_type,extent_id,bytes,blocks from user_extents where segment_name='TEST_SEG' order by segment_name,extent_id ;
TEST_SEG TABLE 0 65536 8
这里我们可以看到段级别对应的区是0-25,和user_segments中看到的26个区数据是一致的。
而这些区块的ID其实就是一个逻辑的编号,是基于段级别的划分。
同样上面的语句,我们简单改一下,查看segment_type为INDEX的区块信息。如下:
SEGMENT_NAME SEGMENT_TYPE EXTENT_ID BYTES BLOCKS
可以很明显看到区块的ID也是从0开始,比如0-7
这里就需要明白,这里的区块0是相对于这个segment_type为INDEX的segment为SYS_C0011978而言的。所以这里的值是一个相对的值,而不是绝对的。
而绝对的位置怎么查找呢,这得依赖于物理结构,能够定位的一个利器就是ROWID,我们取出1行数据来看看。
SQL> select dbms_rowid.ROWID_RELATIVE_FNO(rowid) as
file#,dbms_rowid.ROWID_BLOCK_NUMBER(rowid) as
block#,dbms_rowid.ROWID_ROW_NUMBER(rowid) as row#,a.* from test.test_seg
a where rownum<2;
可以看到是4号数据文件,对应的数据块是134803
要知道一个数据块里存放的数据基本上不是1行数据,而是相关的多行数据。
我们就可以做一个dump来看看。
alter system dump datafile 4 block 134803;
可以通过trace文件看到下面的内容:
tab 0, row 0, @0x1f8a
目前存在3个字段,但是因为当前的LOB字段为空,就直接延迟创建了,只显示出来了两个字段。
而继续做一个update操作,提交事务。
SQL> update test_seg set memo='aaa' where rownum=1;
可以通过trace看到里面的内容已经大大不同,一个最大的变化就是LOB段的延迟创建情况,这个时候修改LOB段数据,所以就会重新初始化。
tab 0, row 0, @0x690
所以对于段来说,里面的信息对应的都是逻辑的概念,地址是逻辑地址,是相对的,而非绝对的。切莫认为一个区可以同时属于多个段。