这是一张非常基本同时也是非常重要的结构图。物理结构很简单,就是操作系统物理块组成数据文件,对于操作系统来说,数据文件跟其他非数据库文件没有区别。重点是逻辑结构。
oracle数据库从逻辑存储结构上来讲,主要包括表空间,段,区,数据块。
他们之间的关系为:一个
一、表空间
从9i开始,oracle支持不同块大小的表空间,
也就是说同一个数据库中,不同表空间的数据块大小可以不一样。假设默认8k的话,还可以创建比如4k、16k、32k、64k等大小的表空间。不过如果有不同块大小的表空间,请记得为它们设置不同的db_nk_cache_size参数,以为这些表空间的数据访问分配内存。
从10g开始,oracle支持重命名表空间,语法是alter tablespace rename to ;这个操作在传输表空间时非常有用,当源和目标的表空间名称不一致时,通过此命令可以方便地更名,这是一大进步。
二、段(segment)
参考上图,一个段可以跨越多个数据文件,但只能在一个表空间中。一个段由多个区(extent)组成。每一个段都有一个单独的data_object_id对应。这里需要额外说明一下data_object_id和object_id的区别。简单的说,object_id对应的是对象,而data_object_id对应的是段。比如一个procedure有object_id,但没有data_object_id,因为它不是段。因为每一个段都唯一对应一个表空间,而每一个段都拥有自己独一无二的data_object_id,所以通过data_object_id,就能唯一定位这个段所在的表空间,这就是rowid的原理。
这里做一个实验,来说明data_object_id和object_id的区别以及一些操作对data_object_id的影响。首先创建一张分区表
SQL>create table part_test(id number,create_time date)
partition by range (id)
(partition part1 values less than (100),
partition part2 values less than (200),
partition part3 values less than (maxvalue));
看一下没有数据时的情况
SQL>select object_name,subobject_name,object_type,object_id,data_object_id from user_objects where object_name = 'PART_TEST';
OBJECT_NAME SUBOBJECT_NAME OBJECT_TYPE OBJECT_ID DATA_OBJECT_ID
-------------------- -------------------- ------------------- ---------- --------------
PART_TEST TABLE 73205
PART_TEST PART1 TABLE PARTITION 73206 73206
PART_TEST PART2 TABLE PARTITION 73207 73207
PART_TEST PART3 TABLE PARTITION 73208 73208
可以看出,初始没有数据的时候,data_object_id和object_id一样。考虑到data_object_id是记录了数据存放的位置,我们看一下先插入数据,再将表truncate之后的情况。
SQL> insert into part_test values(1,sysdate);
1 row created.
SQL> insert into part_test values(101,sysdate+1);
1 row created.
SQL> commit;
Commit complete.
SQL> truncate table part_test;
Table truncated.
SQL> select object_name,subobject_name,object_type,object_id,data_object_id from user_objects where object_name = 'PART_TEST';
OBJECT_NAME SUBOBJECT_NAME OBJECT_TYPE OBJECT_ID DATA_OBJECT_ID
-------------------- -------------------- ------------------- ---------- --------------
PART_TEST PART3 TABLE PARTITION 73208 73208
PART_TEST PART2 TABLE PARTITION 73207 73211
PART_TEST PART1 TABLE PARTITION 73206 73210
PART_TEST TABLE 73205
可以看出,有数据的段,对应的data_object_id改变了,这是因为truncate之后,oracle重新分配了这些段存储数据的空间,因此改变了data_object_id。而没有数据的段,data_object_id没有改变,因为oracle并没有对这些段重新分配数据存储空间。
三、区(extent)
一个区由连续的块组成。这里要强调的就是连续。因此,一个区是不能跨数据文件的(参见上图跟数据文件相连的那条线)
四、块(block)
这是oracle存取数据最小的单位,在建立数据库的时候指定,一旦指定则无法修改。(但在9i之后可以创建不同块大小的表空间,一定程度上解决了这个问题。)
一个块除了了块头、表目录和行目录之外的空间,都可以用来存放数据。按照默认8k大小的块来说,这部分可以真正存放数据的空间是8096字节。然后因为各种其他开销,每行数据的最小长度大约是11个字节,也就是说,每个块最大存放的行数理论值是8096/11=736行。我们可以做个试验来验证一下。
http://www.searchdatabase.com.cn/showcontent_42161.htm