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/28373936/viewspace-1722288/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- rowid的一點總結!
- 一點總結
- 簡單總結一下rowid的相關知識
- 一點ASMM總結ASM
- Duplicate的一點總結
- ash的一點總結
- index和rowid的一點關係!Index
- clickhouse使用的一點總結
- flashback database的一點總結Database
- 使用繫結變數的一點總結!變數
- rownum和rowid,row_number一點應用
- 前端大廠面試一點總結前端面試
- 大學兩年的一點總結
- 總結的小知識點(一)
- 線段樹的一點總結
- 關於ORACLE的一點總結Oracle
- 有關role的一點總結!
- sql loader的一點總結SQL
- data buffer cache的一點總結。
- in、exists操作與null的一點總結Null
- 阿里一面考點分析總結阿里
- HTML5知識點總結(一)HTML
- Vue一些知識點總結Vue
- linux調優的一點總結Linux
- rman的一點簡單總結 1
- 左值右值的一點總結
- 列許可權的一點總結!
- oracle資料字典的一點總結!Oracle
- data buffer cache的一點總結 -- 轉
- profile中password limit的一點總結MIT
- sql load的一點小總結SQL
- dmt、lmt、mssm,assm的一點總結!SSM
- 以前學習sql的一點總結SQL
- 總結兩點
- 關於v-for的一點小總結
- 頂點計劃V第一週總結
- GAN做影象翻譯的一點總結
- GAN做影像翻譯的一點總結