Oracle中的ROWID實現(r10筆記第95天)
一直以來,Oracle的發展是如火如荼,依然非常成熟,無論是行業的人員和資料的豐富程度。對於資料庫的體系結構的內容,下面這張圖我估計很多DBA都快看吐了,每次一提起體系結構,總是會看到這張圖。
而看著10年前的圖,發現依舊能講出不少的東西,很多技術的改變都是添磚加瓦,而動地基之類的改動,那就相當難了,從12c的體系結構可以看出,Oracle真是下了血本了,根深蒂固的基礎架構都要動,而且這個架構貌似以前還是在SQL Server已經有成形的使用。
我想說的是,技術的發展,我們都是其中的分子或者分母,如果說ROWID這個概念有什麼可值得深挖的,估計想想都不大可能。一方面很多人可能因為一些特殊原因瞭解到它的存在,另一方面似乎它可用的空間就不是很大,而且如果想繼續深究它的具體實現方式,這個就更難了。
先來說說ROWID的組成,如果說ROWID的格式如下:
OOOOOO.FFF.BBBBBB.RRR
那麼OOOOOO就是OBJECT_ID,可以透過DBA_OBJECTS查得。
FFF是對應的資料檔案號,可以透過DBA_DATA_FILES或者是V$DATAFILE查到
BBBBBB是資料塊號,這一點尤其值得說一說,資料字典層面,Oracle對外開放的資料字典,最細粒度也就是dba_extents了,如果想看到更細節的資料塊的資訊,那也就只有ROWID可以看到了。
而RRR是對應的行數,也就是row number
ROWID看起來如此強大,能夠定位到如此細節的資訊,那麼ROWID我們有什麼快捷的方式來檢視和管理呢,我們能夠像到的就是DBMS_ROWID了。
比如下面的語句,能夠查到一些很詳細的資訊。
select
rowid as therowid, id,
dbms_rowid.rowid_object(rowid) as objid,
dbms_rowid.rowid_relative_fno(rowid) as relfilenum,
dbms_rowid.ROWID_RELATIVE_FNO(rowid) as absfilenum,
dbms_rowid.rowid_block_number(rowid) as blocknum,
dbms_rowid.rowid_row_number(rowid) as rowslot
from t where id in(1, 2, 500, 501)
order by id;
THEROWID ID OBJID RELFILENUM ABSFILENUM BLOCKNUM ROWSLOT
------------------ ---------- ---------- ---------- ---------- ---------- ----------
AAAVs+AABAAAXHJAAA 1 88894 1 1 94665 0
AAAVs+AABAAAXHJAAB 2 88894 1 1 94665 1
AAAVs+AABAAAXHJAHz 500 88894 1 1 94665 499
AAAVs+AABAAAXHJAH0 501 88894 1 1 94665 500但是可能你也有一種疑惑,這個ROWID看起來格式還真不簡單,到底是咋實現的呢? DBMS_ROWID是不會披露這些資訊的,毫無疑問,這些內容是肯定被加密的。
我們有什麼其他的辦法來解讀呢。首先一種說法是ROWID是根據base64來編碼的。我們有沒有辦法來試一試,這一點還真找到了同樣想法的技術友人,感興趣可以參考這篇。
我們來簡單測試一下。
首先是資料初始化,我們建立一個表,插入10000條資料,兩個SQL輕鬆搞定。
create table t( id integer primary key,name varchar(1));
insert into t select level,'A' name from dual connect by level<=10000;
我們檢視幾行資料。
SQL> select rowid from t where id<=2;
ROWID
------------------
AAAVs+AABAAAXHJAAA
AAAVs+AABAAAXHJAAB
末尾的3位是行數,那麼我們解讀一下它吧。
SQL> select substr(rowid, 16, 3)
from t where id <= 2;
SUBSTR(ROWID,16,3)
------------------
AAA
AAB這一點很顯然就是如此,沒有什麼特別之處,而base64是要求至少24位,所以我們可以嘗試再補充一位。
SQL> select LPAD(substr(rowid, 16, 3), 4, 'A')
from t where id <= 2;
LPAD(SUBSTR(ROWID,16,3),
------------------------
AAAA
AAAB
下面的這個步驟就很值得玩味了,那就是使用base64的方法來處理。
SQL> select utl_encode.base64_decode(utl_raw.cast_to_raw(lpad(substr(rowid, 16, 3), 4, 'A')))
from t where id in(1, 2, 500, 501);
------------------------------------
000000
000001
0001F3
0001F4可以看出這個現實的結果是行數,但是實際上這個是十六進位制的方式。沃恩需要再這個基礎上進一步轉換。
SQL> select to_number(utl_encode.base64_decode(utl_raw.cast_to_raw(lpad(substr(rowid, 16, 3), 4, 'A'))), 'XXXXXX') as rowslot
from t where id in(1, 2, 500, 501);
ROWSLOT
----------
0
1
499
500
如此一來,整個過程是清晰了很多,那麼這個說法到底是否靠譜呢。
我們可以使用它來得到和dbms_rowid同樣的效果。
select rowid as therowid, id,
to_number(utl_encode.base64_decode(utl_raw.cast_to_raw(lpad(substr(rowid,1, 6), 8, 'A'))), 'XXXXXXXXXXXX') as objid,
to_number(utl_encode.base64_decode(utl_raw.cast_to_raw(lpad(substr(rowid, 7, 3), 4, 'A'))), 'XXXXXX') as filenum,
to_number(utl_encode.base64_decode(utl_raw.cast_to_raw(lpad(substr(rowid, 10, 6), 8, 'A'))), 'XXXXXXXXXXXX') as blocknum,
to_number(utl_encode.base64_decode(utl_raw.cast_to_raw(lpad(substr(rowid, 16, 3), 4, 'A'))), 'XXXXXX') as rowslot
from t where id <= 2 ;
THEROWID ID OBJID FILENUM BLOCKNUM ROWSLOT
------------------ ---------- ---------- ---------- ---------- ----------
AAAVs+AABAAAXHJAAA 1 88894 1 94665 0
AAAVs+AABAAAXHJAAB 2 88894 1 94665
所以說如此一來整個ROWID的實現方式就一目瞭然了,而在這個測試中如果結合ROWNUM其實也就更有意思了。我們後續來揉在一起來對比一下。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28211342/viewspace-2129514/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 最近看過的書(r10筆記第92天)筆記
- 《亂》觀後感(r10筆記第93天)筆記
- 《共同警戒區》觀後感(r10筆記第97天)筆記
- 資料遷移整合中的幾個問題總結(r10筆記第99天)筆記
- 值得推薦的幾部日本電影(三)(r10筆記第29天)筆記
- Oracle中rowid的用法Oracle
- 【oracle中rowid的用法】Oracle
- 使用SQL來分析資料庫引數(一)(r10筆記第68天)SQL資料庫筆記
- oracle實驗記錄 (dbms_rowid使用)Oracle
- 【筆記】oracle 陣列實現筆記Oracle陣列
- 一條SQL語句的執行計劃變化探究(r10筆記第9天)SQL筆記
- oracle中的Rowid和UrowidOracle
- oracle中rownum和rowid的區別Oracle
- 《Effective C++》第5章 實現-讀書筆記C++筆記
- oracle 表中的rowid是什麼意思Oracle
- 【ROWID】Oracle rowid說明Oracle
- oracle rowidOracle
- Oracle中rownum與rowid使用上的問題Oracle
- MySQL中的_rowidMySql
- oracle rowid 的含義Oracle
- ORACLE ROWID (zt)Oracle
- Linux核心設計與實現(原書第3版)筆記Linux筆記
- 相同update語句在MySQL,Oracle的不同表現(r12筆記第30天)MySqlOracle筆記
- oracle單條sql與plsql rowid插入記錄小記OracleSQL
- 【筆記】樹的表示與實現筆記
- oracle常用包之dbms_rowid oracle rowid含義分析Oracle
- 第63節:Java中的Spring MVC簡介筆記JavaSpringMVC筆記
- MySQL中的derived table(r12筆記第47天)MySql筆記
- 【筆記】堆及其實現筆記
- 第3章筆記筆記
- oracle rowid詳解Oracle
- Oracle rowid 詳解Oracle
- Oracle ROWID-1Oracle
- Oracle ROWID-2Oracle
- oracle rowid (轉載)Oracle
- 物化檢視實現的特殊資料複製(r11筆記第42天)筆記
- Oracle高階培訓 第5課 學習筆記Oracle筆記
- Oracle高階培訓 第6課 學習筆記Oracle筆記