天天看點

rowid一點總結

實體rowid兩種格式:

受限rowid  (8i之前)

擴充rowid  (8i以後)

Extended rowids use a base 64 encoding of the

physical address for each row selected. The

encoding characters are A-Z, a-z, 0-9, +, and /

rowid :在oracle中稱僞列,不是建立表的時候的某個列。如果要删除兩行相同的資料,可以運用rowid。

              rowid記錄這一行資料在磁盤上的實際存儲的實體位置。desc t和 select * from t均查不出來rowid

SQL> connect scott/tiger;

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0

Connected as scott

SQL>

SQL>

SQL> select t3.* ,rowid from t3;

 ID  NAME         ROWID

-- -------------------------------

 1    a      AAAM40AAGAAAAAMAAA

 2    b      AAAM40AAGAAAAAMAAB

 3    c      AAAM40AAGAAAAAMAAC

--------------------------------

以擴充rowid格式為例:  AAAM40AAGAAAAAMAAA

rowid一共18位,分為四個部分

AAAM40: 資料對象編号(data object number)  :表示的是t2這個表段的編号,在dba_objects這個視圖中,用 data_object_id表示。注意 object_id是對象編号,data_object_id是資料段編号,

它跟實體存儲位置有關。

         The data object number that identifies the database segment (AAAM40 in the example). Schema objects in thesame segment, such as a cluster of tables,have the same data object number.

AAG :         相對檔案編号 (relative file number) 

AAAAAM: 包含資料行的資料塊編号(block number) 

AAA :         行編号( row number)

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

 OBJECT_ID  DATA_OBJECT_ID

----------  --------------

     52657          52786

SQL> alter table t2 rename to t3;

Table altered

SQL>

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

 OBJECT_ID DATA_OBJECT_ID

---------- --------------

     52657          52786

SQL>

SQL> select  TABLESPACE_NAME from user_tables where table_name='T3';

TABLESPACE_NAME

------------------------------

USERS

SQL> alter table t3 move tablespace TT;

Table altered

可以看到,在移動表空間後,資料段發生了變化,是以對象編号也發生了變化,如下:

SQL> select t3.* ,rowid from t3;

 ID  NAME         ROWID

-- -------------------------------

 1    a      AAAM40AAGAAAAAMAAA

 2    b      AAAM40AAGAAAAAMAAB

 3    c      AAAM40AAGAAAAAMAAC

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

 OBJECT_ID DATA_OBJECT_ID

---------- --------------

     52657          52787

=====================================================

哪些操作會使資料對象(段)編号發生變化呢 ?

SQL> truncate table t3;

Table truncated

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

 OBJECT_ID DATA_OBJECT_ID

---------- --------------

     52657          52788

truncate操作是ddl指令,隻修改中繼資料(中繼資料放在資料字典中,存放在system表空間中),不涉及到修改表資料。

           truncate  t3 時,隻修改system表空間對t3表的描述。實際上,把原來的T3表重命名,然後重新建立了

           一個新的空表T3 ,是以truncate 很快,truncate一個幾百G的表和truncate 幾條資料的表時間差不多。

====================================================

delete 表的某一列資料,oracle到底做了什麼?

先把這一列所占的空間釋放掉,其次要把中繼資料删除掉,是以在大表上删除某一列,非常慢。

SQL> show user;

User is "scott"

SQL> select count(*) from t;

  COUNT(*)

----------

   1611552

SQL> select bytes/1024/1024 M from dba_segments where segment_name='T';

         M

----------

       178

SQL> desc t;

Name           Type          Nullable Default Comments

-------------- ------------- -------- ------- --------

OWNER          VARCHAR2(30)  Y                        

OBJECT_NAME    VARCHAR2(128) Y                        

SUBOBJECT_NAME VARCHAR2(30)  Y                        

OBJECT_ID      NUMBER        Y                        

DATA_OBJECT_ID NUMBER        Y                        

OBJECT_TYPE    VARCHAR2(19)  Y                        

CREATED        DATE          Y                        

LAST_DDL_TIME  DATE          Y                        

TIMESTAMP      VARCHAR2(19)  Y                        

STATUS         VARCHAR2(7)   Y                        

TEMPORARY      VARCHAR2(1)   Y                        

GENERATED      VARCHAR2(1)   Y                        

SECONDARY      VARCHAR2(1)   Y                        

SQL> execute dbms_stats.gather_table_stats('SCOTT','T');

SQL> alter table t drop column OBJECT_TYPE;

Table altered

SQL>

SQL>

SQL> execute dbms_stats.gather_table_stats('SCOTT','T');

PL/SQL procedure successfully completed

SQL> select num_rows,blocks from user_tables where table_name='T';

  NUM_ROWS     BLOCKS

---------- ----------

   3225195      44287

SQL>

可以看到blocks沒有發生變化,但是num_rows發生了變化(有可能比之前的值更大)

=========================

大表删除列

1:删除列,但不釋放空間

SQL> desc t;

Name           Type        Nullable Default Comments

-------------- ----------- -------- ------- --------

OBJECT_ID      NUMBER      Y                        

DATA_OBJECT_ID NUMBER      Y                        

CREATED        DATE        Y                        

LAST_DDL_TIME  DATE        Y                        

STATUS         VARCHAR2(7) Y                        

TEMPORARY      VARCHAR2(1) Y                        

GENERATED      VARCHAR2(1) Y                        

SECONDARY      VARCHAR2(1) Y                        

SQL>

SQL>

SQL> alter table t set unused column status;

oracle執行這句話,不釋放空間,它隻重命名了列,可以從select * from dba_tab_cols where wner='SCOTT' 驗證

SQL> desc t;

Name           Type        Nullable Default Comments

-------------- ----------- -------- ------- --------

OBJECT_ID      NUMBER      Y                        

DATA_OBJECT_ID NUMBER      Y                        

CREATED        DATE        Y                        

LAST_DDL_TIME  DATE        Y                        

TEMPORARY      VARCHAR2(1) Y                        

GENERATED      VARCHAR2(1) Y                        

SECONDARY      VARCHAR2(1) Y                        

2:使用這個指令以後,就将原來的status列删除掉了。(釋放了空間)

SQL> alter table t drop unused columns;

Table altered

然後用 select * from dba_tab_cols where wner='SCOTT' 可以驗證

========

3:将表空間offline後,可以删除表中的資料 (為什麼?)

SQL> select table_name,tablespace_name from user_tables;

TABLE_NAME                     TABLESPACE_NAME

------------------------------ ------------------------------

DEPT                           USERS

EMP                            USERS

BONUS                          USERS

SALGRADE                       USERS

EMPLOYEES                      USERS

T                              USERS

PLCH_COMMISSIONS               USERS

PLCH_SALARIES                  USERS

T3                             TT

9 rows selected

SQL> alter tablespace USERS offline;

Tablespace altered

SQL> select count(*) from t;

select count(*) from t

ORA-00376: 此時無法讀取檔案 4

ORA-01110: 資料檔案 4: 'C:\ORADATA\ORCL\USERS01.DBF'

SQL>

SQL> desc t;

Name           Type        Nullable Default Comments

-------------- ----------- -------- ------- --------

OBJECT_ID      NUMBER      Y                        

DATA_OBJECT_ID NUMBER      Y OBJECT_ID                       

CREATED        DATE        Y                        

LAST_DDL_TIME  DATE        Y                        

TEMPORARY      VARCHAR2(1) Y                        

GENERATED      VARCHAR2(1) Y                        

SECONDARY      VARCHAR2(1) Y                        

SQL>

SQL> drop table t;

Table dropped

SQL>

SQL> flashback table t to before drop;

Done

SQL> alter tablespace users online;

Tablespace altered

SQL> select count(*) from t;

  COUNT(*)

----------

   3222976

将表空間offline以後,删除表是ddl操作,操作的是中繼資料,它存放在system表空間中。

====================================================================

AAG :   相對檔案編号 (relative file number) ,用dba_data_files 中的relative_fno字段表示。

         一個database最多包含65536個資料檔案,一個表空間最多包含1023個資料檔案。

         因為G 轉換為十進制就是6,那麼AAG就表示6号資料檔案

SQL> select file_name,relative_fno from dba_data_files where tablespace_name='TT';

FILE_NAME                           RELATIVE_FNO

-------------------------------------------------

C:\ORADATA\ORCL\TT.DBF                 6

AAAAAM : 資料塊編号(block number) ,M轉換為十進制是12

可以看到

SQL> select t3.* ,rowid from t3;

ID NAME          ROWID

-------------------------

1  a        AAAM40AAGAAAAAMAAA

(1,'a')這條資料存放在6号資料檔案的第12号塊上       

AAA :   行編号( row number)

         可以看到該資料檔案塊大小為8k ,一個資料塊可以存放很多行資料,它表示在塊上的第幾條資料。

         AAA轉換後是0,0 表示在這個塊上的第1條資料

SQL> show parameter db_block_size;

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

db_block_size                        integer     8192

rowid是64進制,編碼格式

A~Z   0~25

a~z   26~51

0~9   52~61

+     62

/     63

SQL> select t3.* ,rowid from t3;

ID NAME          ROWID

-------------------------

1  a        AAAM40AAGAAAAAMAAA

AAAM40 AAG   AAAAAM  AAA

通過dba_objects 視圖,檢視到data_object_id 為52788 ,那麼現在看下64進制數和十進制如何轉換的,

AAAM40 對應的十進制編碼為

A  A  A  M   4  0

0  0  0  12  56 52

SQL> select 12*64*64+56*64+52 from dual;

12*64*64+56*64+52

-----------------

            52788

其實oracle也提供了一些包,計算rowid

包 dbms_rowid 裡面含有很多函數

SQL> desc dbms_rowid;

Element                Type     

---------------------- ---------

ROWID_TYPE_RESTRICTED  CONSTANT 

ROWID_TYPE_EXTENDED    CONSTANT 

ROWID_IS_VALID         CONSTANT 

ROWID_IS_INVALID       CONSTANT 

ROWID_OBJECT_UNDEFINED CONSTANT 

ROWID_CONVERT_INTERNAL CONSTANT 

ROWID_CONVERT_EXTERNAL CONSTANT 

ROWID_INVALID          EXCEPTION

ROWID_BAD_BLOCK        EXCEPTION

ROWID_CREATE           FUNCTION 

ROWID_INFO             PROCEDURE

ROWID_TYPE             FUNCTION 

ROWID_OBJECT           FUNCTION 

ROWID_RELATIVE_FNO     FUNCTION 

ROWID_BLOCK_NUMBER     FUNCTION 

ROWID_ROW_NUMBER       FUNCTION 

ROWID_TO_ABSOLUTE_FNO  FUNCTION 

ROWID_TO_EXTENDED      FUNCTION 

ROWID_TO_RESTRICTED    FUNCTION 

ROWID_VERIFY           FUNCTION 

SQL>

SQL> select t3.*,rowid from t3;

ID NAME            ROWID

----------------------------------

1  a         AAAM40AAGAAAAAMAAA

2  b         AAAM40AAGAAAAAMAAB

3  c         AAAM40AAGAAAAAMAAC

SQL>

SQL> select dbms_rowid.rowid_object(rowid) obj, dbms_rowid.rowid_relative_fno(rowid) fno,

  2  dbms_rowid.rowid_block_number(rowid) bno, dbms_rowid.rowid_row_number(rowid) rno

  3  from t3;

       OBJ        FNO        BNO        RNO

---------- ---------- ---------- ----------

     52788          6         12          0

     52788          6         12          1

     52788          6         12          2

也可以通過dbms_rowid這個包來構造rowid 。

如下就構造了t3表的第一行資料的rowid資訊

SQL> select dbms_rowid.rowid_create(1,52788,6,12,0) from dual;

DBMS_ROWID.ROWID_CREATE(1,5278

------------------------------

AAAM40AAGAAAAAMAAA

其中1表示rowid的兩種類型(0表示受限制,1表示擴充)

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/24862808/viewspace-730784/,如需轉載,請注明出處,否則将追究法律責任。

轉載于:http://blog.itpub.net/24862808/viewspace-730784/