我们经常使用的数据字典视图
实验环境构建
//我们选择10gR2版本
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 – Production
//构建实验数据表
SQL> create table t as select * from dba_objects;
Table created
//数据字典信息展示
SQL> select object_id,data_object_id from user_objects where object_name='T';
OBJECT_ID DATA_OBJECT_ID
---------- --------------
54038 54038
SQL> select segment_name, header_file, header_block from dba_segments where segment_name='T' and wner='SCOTT';
SEGMENT_NAME HEADER_FILE HEADER_BLOCK
-------------------- ----------- ------------
T 4 4203
此时,我们注意一下:试验的数据表T,其object_id为54038,data_object_id相同也为54038。物理段位置上,位于4号数据文件,头块编号为4203。
数据字典分析
首先我们分析一下dba_objects数据字典视图两个对应列的来源。从视图的解释信息上看,object_id和data_object_id分别为:
OBJECT_ID:Object number of the object
DATA_OBJECT_ID: Object number of the segment which contains the object
从视图注释信息上看,object_id的含义是对象的唯一性编号。而data_object_id表示的是数据表对应的段位置编号。简单的说,一个表示逻辑唯一编号,一个表示物理存储上的唯一编号。
分析数据字典dba_objects来源,可以抽丝剥茧。检查dba_objects视图的基础来源。这时候我们的方法很多,比如使用dbms_metadata.get_ddl方法。这次我们直接研究数据字典的生成脚本catalog.sql文件中的内容。
create or replace view DBA_OBJECTS
(OWNER, OBJECT_NAME, SUBOBJECT_NAME, OBJECT_ID, DATA_OBJECT_ID,
OBJECT_TYPE, CREATED, LAST_DDL_TIME, TIMESTAMP, STATUS,
TEMPORARY, GENERATED, SECONDARY)
as
select u.name, o.name, o.subname, o.obj#, o.dataobj#,
decode(o.type#, 0, 'NEXT OBJECT', 1, 'INDEX', 2, 'TABLE', 3, 'CLUSTER',
(篇幅原因,省略部分……)
'UNDEFINED'),
o.ctime, o.mtime,
to_char(o.stime, 'YYYY-MM-DD:HH24:MI:SS'),
decode(o.status, 0, 'N/A', 1, 'VALID', 'INVALID'),
decode(bitand(o.flags, 2), 0, 'N', 2, 'Y', 'N'),
decode(bitand(o.flags, 4), 0, 'N', 4, 'Y', 'N'),
decode(bitand(o.flags, 16), 0, 'N', 16, 'Y', 'N')
from sys.obj$ o, sys.user$ u
(篇幅原因,省略部分…)
上述为catalog.sql脚本中对dba_objects的定义片段,处于篇幅的考虑将于本篇无关的内容加以省略。注意:这个是Oracle10gR2的dba_objects定义,在11g中存在一些差异,留待以后的讨论。
从上面的脚本中,我们确定dba_objects视图对象的主要信息来源自底层数据字典表obj$和user$。我们之前讨论过关于Oracle层次结构的数据字典,http://space.itpub.net/17203031/viewspace-686814,obj$属于底层数据字典结构。其中,我们关注的object_id和data_object_id字段就是对应obj$数据表的obj#和dataobj#字段。
那么,这两个字段在obj$中的解释是什么呢?因为obj$数据表对应列没有comment信息。我们搜索sql.bsp文件,发现如下的文件片段。
create table obj$ /* object table */
( obj# number not null, /* object number */
/* DO NOT CREATE INDEX ON DATAOBJ# AS IT WILL BE UPDATED IN A SPACE
* TRANSACTION DURING TRUNCATE */
dataobj# number, /* data layer object number */
owner# number not null, /* owner user number */
(篇幅原因,省略部分…)
在sql.bsp脚本中,定义了数据库基础结构表的内容,其中一些注释信息,往往包含着重要信息内容。这里我们发现了obj#和dataobj#的一些端倪。
首先,obj#是一个对象标志,在数据库中作为一个对象的唯一标识。而dataobj#给出的内部说明是“data layer object number”,是数据层对象的编号。并且最值得注意的是上面关于dataobj#的描述:Oracle要求不要对这个数据列加索引,因为该列取值会由于进行truncate操作而发生变化。
在数据字典obj$的内容说明中,我们可以猜测dataobj#是一种描述对象物理存储的标志。truncate操作虽然从效果上是快速进行数据删除,但是本质上是一种ddl语句,重构数据结构。下面我们通过实验进行说明。
Truncate Table实验
还是刚刚环境准备的实验数据表。我们分别进行一般性delete删除和truncate两种删除操作,比较变化效果。
//启用跟踪文件方法
SQL> alter session set events '10046 trace name context forever, level 4';
Session altered
SQL> delete t;
50355 rows deleted
SQL> commit;
Commit complete
SQL> select f_get_trace_name from dual;
F_GET_TRACE_NAME
--------------------------------------
D:\ORACLE\PRODUCT\10.2.0\ADMIN\ORCL\UDUMP\orcl_ora_1236.trc
之后,我们观察数据表T的逻辑物理结构情况。
SQL> select object_id,data_object_id from user_objects where object_name='T';
OBJECT_ID DATA_OBJECT_ID
---------- --------------
54038 54038
SQL> col segment_name for a20;
SQL> select segment_name, header_file, header_block from dba_segments where segment_name='T' and wner='SCOTT';
SEGMENT_NAME HEADER_FILE HEADER_BLOCK
-------------------- ----------- ------------
T 4 4203
发现,对象编号和物理编号都没有发生变化。对应的segment_name结构也没有任何的变化,包括文件位置和段头块编号等。同时分析跟踪文件orcl_ora_1236.trc,也没有发现更新obj$数据表的连带操作痕迹。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/17203031/viewspace-690629/ ,如需转载,请注明出处,否则将追究法律责任。