深入解析:DBA_OBJECTS中的OBJECT_ID与DATA_OBJECT_ID的区别

墨墨导读:在Oracle dba_objects视图中存在object_id和data_oubject两个列,已经存在object_id列了为什么还会有一个data_object_id列呢,这两个列有什么区别?通过本文了解一下。

object_id和data_object_id同样是表示数据库对象的一个唯一标志,但是object_id表示的是逻辑id,data_object_id表示的是物理id。只有表,索引,undo这些有实际物理存储位置的对象才有data_object_id, 而一些没有物理属性的object 不存在data_object_id,例如procedure,function,package,data type,db link,mv定义,view定义,临时表,分区表定义等等这些object都是没有对应着某个segment,因此它们的data_object_id都为空。

大多数情况下两者是相等的。但对object 进行truncate,move, rebuild 等操作后,data_object_id就会发生改变,而object_id不会改变。

create table tab1 as select * from emp;
SQL>  create table tab1 as select * from emp;


Table created.


create index ind_tab1_pk on tab1(empno);
SQL> create index ind_tab1_pk on tab1(empno);


Index created.


select object_name,object_type,subobject_name,object_id,data_object_id from dba_objects where object_name in ('TAB1','IND_TAB1_PK');


SQL> select object_name,object_type,object_id,data_object_id from dba_objects where object_name in ('TAB1','IND_TAB1_PK');


OBJECT_NAME                          object_type        OBJECT_ID DATA_OBJECT_ID
------------------------------ -----------------------  ------------ ---------------
IND_TAB1_PK                             INDEX               74827          74827
TAB1                                    TABLE               74826          74826


SQL> create view v_emp as select * from emp;


View created.


select object_name,object_type,object_id,data_object_id from dba_objects where object_name='V_EMP';
SQL> select object_name,object_type,object_id,data_object_id from dba_objects where object_name='V_EMP';


OBJECT_NAME                    OBJECT_TYPE          OBJECT_ID DATA_OBJECT_ID
------------------------------ ------------------- ---------- --------------
V_EMP                          VIEW                     74832

通过上面查询上面创建的表、索引以及视图可以看到,表和索引这种存在物理存储的是数据库对象是有data_object_id的,而像视图这样的不存在物理存储的数据库对象是没有data_object_id的。

下面对存在data_object_id的数据库对象进测试查看data_object_id的变化与什么有关。

–删除表中的数据查看object_id和data_object_id的变化

SQL> delete from tab1 where empno=7788;


1 row deleted.


SQL> commit;


Commit complete.


SQL> select object_name,object_type,object_id,data_object_id from dba_objects where object_name in ('TAB1','IND_TAB1_PK');


OBJECT_NAME                          object_type        OBJECT_ID DATA_OBJECT_ID
------------------------------ -----------------------  ------------ ---------------
IND_TAB1_PK                             INDEX               74827          74827
TAB1                                    TABLE               74826          74826

–对表进行TRUNCATE查看object_id和data_object_id的变化

truncate table tab1;
SQL> truncate table tab1;


Table truncated.


SQL> select object_name,object_type,object_id,data_object_id from dba_objects where object_name in ('TAB1','IND_TAB1_PK');


OBJECT_NAME                    object_type                  OBJECT_ID DATA_OBJECT_ID
------------------------------ ---------------------------- ---------- --------------
IND_TAB1_PK                      INDEX                         74827          74828
TAB1                             TABLE                         74826          74829

–对表进行MOVE查看object_id和data_object_id的变化

alter table tab1 move;
SQL> alter table tab1 move;


Table altered.


SQL> select object_name,object_type,object_id,data_object_id from dba_objects where object_name in ('TAB1','IND_TAB1_PK');


OBJECT_NAME                   object_type                  OBJECT_ID DATA_OBJECT_ID
-------------------------- ------------------------------ ---------- --------------
IND_TAB1_PK                    INDEX                           74827         74828
TAB1                           TABLE                           74826         74830

–对索引进行REBUILD查看object_id和data_object_id的变化

alter index ind_tab1_pk rebuild;
SQL> alter index ind_tab1_pk rebuild;


Index altered.
SQL> select object_name,object_type,object_id,data_object_id from dba_objects where object_name in ('TAB1','IND_TAB1_PK');


OBJECT_NAME                    object_type                  OBJECT_ID DATA_OBJECT_ID
----------------------------- ---------------------------- ---------- --------------
IND_TAB1_PK                     INDEX                          74827         74831
TAB1                            TABLE                          74826         74830

从上面的测试来看当在对表做了TRUNCATE时,表TAB1和表上的索引的data_object_id都发生了变化,在对表做move的时候只有表的data_object_id发生了变化,在对索引重建的时候只有索引的data_object_id发生了变化。在删除表中的数据的时候data_object_id却没有变化。原因是什么呢?


–查看视图DBA_OBJECTS的定义

SQL>  select text from dba_views where view_name='DBA_OBJECTS';


TEXT
--------------------------------------------------------------------------------
select u.name, o.name, o.subname, o.obj#, o.dataobj#,
       decode(o.type#, 0, 'NEXT OBJECT', 1, 'INDEX', 2, 'TABLE', 3, 'CLUSTER',
                      4, 'VIEW', 5, 'SYNONYM', 6, 'SEQUENCE',
                      7, 'PROCEDURE', 8, 'FUNCTION', 9, 'PACKAGE',
                      11, 'PACKAGE BODY', 12, 'TRIGGER',
                      13, 'TYPE', 14, 'TYPE BODY',
                      19, 'TABLE PARTITION', 20, 'INDEX PARTITION', 21, 'LOB',
                      22, 'LIBRARY', 23, 'DIRECTORY', 24, 'QUEUE',
                      28, 'JAVA SOURCE', 29, 'JAVA CLASS', 30, 'JAVA RESOURCE',
                      32, 'INDEXTYPE', 33, 'OPERATOR',
                      34, 'TABLE SUBPARTITION', 35, 'INDEX SUBPARTITION',
                      40, 'LOB PARTITION', 41, 'LOB SUBPARTITION',
                      42, NVL((SELECT 'REWRITE EQUIVALENCE'
                               FROM sum$ s
                               WHERE s.obj#=o.obj#
                                     and bitand(s.xpflags, 8388608) = 8388608),
                              'MATERIALIZED VIEW'),
                      43, 'DIMENSION',
                      44, 'CONTEXT', 46, 'RULE SET', 47, 'RESOURCE PLAN',
                      48, 'CONSUMER GROUP',
                      51, 'SUBSCRIPTION', 52, 'LOCATION',
                      55, 'XML SCHEMA', 56, 'JAVA DATA',
                      57, 'EDITION', 59, 'RULE',
                      60, 'CAPTURE', 61, 'APPLY',
                      62, 'EVALUATION CONTEXT',
                      66, 'JOB', 67, 'PROGRAM', 68, 'JOB CLASS', 69, 'WINDOW',
                      72, 'SCHEDULER GROUP', 74, 'SCHEDULE', 79, 'CHAIN',
                      81, 'FILE GROUP', 82, 'MINING MODEL', 87, 'ASSEMBLY',
                      90, 'CREDENTIAL', 92, 'CUBE DIMENSION', 93, 'CUBE',
                      94, 'MEASURE FOLDER', 95, 'CUBE BUILD PROCESS',
                      100, 'FILE WATCHER', 101, 'DESTINATION',
                     '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'),
       o.namespace,
       o.defining_edition
from sys."_CURRENT_EDITION_OBJ" o, sys.user$ u
where o.owner# = u.user#
  and o.linkname is null
  and (o.type# not in (1  /* INDEX - handled below */,
                      10 /* NON-EXISTENT */)
       or
       (o.type# = 1 and 1 = (select 1
                              from sys.ind$ i
                             where i.obj# = o.obj#
                               and i.type# in (1, 2, 3, 4, 6, 7, 9))))
  and o.name != '_NEXT_OBJECT'
  and o.name != '_default_auditing_options_'
  and bitand(o.flags, 128) = 0
union all
select u.name, l.name, NULL, to_number(null), to_number(null),
       'DATABASE LINK',
       l.ctime, to_date(null), NULL, 'VALID','N','N', 'N', NULL, NULL
from sys.link$ l, sys.user$ u
where l.owner# = u.user#


SQL> desc dba_objects
 Name                                                                                                              Null?    Type
 ----------------------------------------------------------------------------------------------------------------- -------- ----------------------------------------------------------------------------
 OWNER                                                                                                                      VARCHAR2(30)
 OBJECT_NAME                                                                                                                VARCHAR2(128)
 SUBOBJECT_NAME                                                                                                             VARCHAR2(30)
 OBJECT_ID                                                                                                                  NUMBER
 DATA_OBJECT_ID                                                                                                             NUMBER
 OBJECT_TYPE                                                                                                                VARCHAR2(19)
 CREATED                                                                                                                    DATE
 LAST_DDL_TIME                                                                                                              DATE
 TIMESTAMP                                                                                                                  VARCHAR2(19)
 STATUS                                                                                                                     VARCHAR2(7)
 TEMPORARY                                                                                                                  VARCHAR2(1)
 GENERATED                                                                                                                  VARCHAR2(1)
 SECONDARY                                                                                                                  VARCHAR2(1)
 NAMESPACE                                                                                                                  NUMBER
 EDITION_NAME                                                                                                               VARCHAR2(30)

data_object_id在dba_objects视图中的顺序可以对应到视图定义中的o.dataobj#字段,该字段来自于视图_CURRENT_EDITION_OBJ

接着查看该视图的定义

SQL> select text from dba_views where view_name='_CURRENT_EDITION_OBJ';
TEXT--------------------------------------------------------------------------------select o."OBJ#",o."DATAOBJ#",o."OWNER#",o."NAME",o."NAMESPACE",o."SUBNAME",o."TYPE#",o."CTIME",o."MTIME",o."STIME",o."STATUS",o."REMOTEOWNER",o."LINKNAME",o."FLAGS",o."OID$",o."SPARE1",o."SPARE2",o."SPARE3",o."SPARE4",o."SPARE5",o."SPARE6",
       o.spare3,       case when (o.type# not in (4,5,7,8,9,10,11,12,13,14,22,87) or                  bitand(u.spare1, 16) = 0) then         null       when (u.type# = 2) then        (select eo.name from obj$ eo where eo.obj# = u.spare2)       else        'ORA$BASE'       endfrom obj$ o, user$ uwhere o.owner# = u.user#  and (   /* non-versionable object */          (   o.type# not in (4,5,7,8,9,10,11,12,13,14,22,87,88)           or bitand(u.spare1, 16) = 0)          /* versionable object visible in current edition */       or (    o.type# in (4,5,7,8,9,10,11,12,13,14,22,87)           and (   (u.type# <> 2 and                    sys_context('userenv', 'current_edition_name') = 'ORA$BASE')
                or (u.type# = 2 and                    u.spare2 = sys_context('userenv', 'current_edition_id'))                or exists (select 1 from obj$ o2, user$ u2                           where o2.type# = 88                             and o2.dataobj# = o.obj#                             and o2.owner# = u2.user#                             and u2.type#  = 2                             and u2.spare2 =                                  sys_context('userenv', 'current_edition_id'))               )          )      )


从该视图的定义中可以看到o.DATAOBJ#字段来自于内部表obj,而obj.dataobj#又对应着seg$.HWMINCR

select max(HWMINCR) from sys.seg$;SQL> select max(HWMINCR) from sys.seg$;
MAX(HWMINCR)------------       74831

这里的HWMINCR就是data_object_id的来源,每次seg里生成新的一条记录都会增加HWMINCR这个值,同时obj.dataobj#也会跟着变化。

从前面可以看到74831是tab1表上的索引ind_tab1_pk的data_object_id,那么现在对该索引进行rebuild再查看seg$.HWMINCR最大值的变化

alter index ind_tab1_pk rebuild;
SQL> alter index ind_tab1_pk rebuild;
Index altered.
SQL> select max(HWMINCR) from sys.seg$;
MAX(HWMINCR)------------       74833


这时候发现max(HWMINCR)变为了74833,这里的HWMINCR就是data_object_id的来源,每当数据库上存在物理段的对象段发生变化的时候都会在seg里生成新的一条记录增加HWMINCR这个值,同时obj.dataobj#也会跟着变化。最后在视图dba_objects中对应对象的data_object_id值也会发生变化。

墨天轮原文链接:https://www.modb.pro/db/24365(复制到浏览器中打开或者点击“阅读原文”)

推荐阅读:144页!分享珍藏已久的数据库技术年刊

数据和云

ID:OraNews

如有收获,请划至底部,点击“在看”,谢谢!

点击下图查看更多 ↓

云和恩墨大讲堂 | 一个分享交流的地方

长按,识别二维码,加入万人交流社群

请备注:云和恩墨大讲堂

  点个“在看”

你的喜欢会被看到❤

原文地址:https://www.cnblogs.com/hzcya1995/p/13311725.html