oracle學習總結 一 ROWID

2021-08-22 05:46:53 字數 3267 閱讀 7586

一.rowid簡介

rowid就是唯一標誌記錄物理位置的乙個id,在oracle 8版本以前,rowid由file#+block#+row#組成,占用6個bytes的空間,10 bit 的 file# ,22bit 的 block# ,16 bit 的 row#。

從oracle 8開始rowid變成了extend rowid,由data_object_id#+rfile#+block#+row#組成,占用10個bytes的空間, 32bit的 data_object_id#,10 bit 的 rfile#,22bit 的 block#,16 bit 的 row#.由於rowid的組成從file#變成了rfile#,所以資料檔案數的限制也從整個庫不能超過1023個變成了每個表空間不能超過1023個 資料檔案。

說了rowid的組成,那麼我們再來看看rowid在索引裡面占用的位元組數又是什麼樣子的。在oracle 8以前索引中儲存的rowid占用位元組數也是6bytes,在oracle8之後,雖然oracle使用了extend rowid,但是在普通索引裡面依然儲存了bytes的rowid,只有在global index中儲存的是10bytes的extend rowid,而extend rowid也是global index出現的乙個必要條件,下面我們會解釋原因。

為什麼golbal index需要把data_object_id#也包含在index rowid entry中呢?如果不包含會這麼樣?首先我們需要知道index的rowid entry的存在是為了能根據它找到表的這條記錄存在哪個具體的物理位置,我們需要知道它在哪個資料檔案,在哪個block,在那一行,普通的索引 oracle根據rfile#,block#,row#就可以知道了,但是partition table可以分布在多個表空間,也就是可以分布在多個資料檔案,當我們建立local index時,index rowid entry並不包含data_object_id#,因為oracle可以知道這個index對應的是哪乙個table分割槽,並可以得到table分割槽的 ts#(tablespace號),那麼oracle根據ts#和rfile#就可以找到具體的資料檔案。但是如果換成是golbal index,如果不包含data_object_id#,那麼我們並不能知道這個索引對應著哪個表分割槽,也自然不能知道它的rfile#和file#的轉 換關係,所以它將找不到所對應的記錄。包含data_object_id#後,oracle可以根據data_object_id#實現rfile#和 file#的轉換然後找到記錄對應的物理位置。需要注意的是要理解以上概念我們還是需要了解file#和rfile#的區別。

二.比較file#和rfile#

oracle資料檔案為什麼存在file#和rfile#?

歸根結底的原因是因為 rowid 的儲存格式造成的,因為 rowid 中檔案編號標誌只有10bit,最大資料容量1024,由於不存在0編號檔案,所以實際上只允許1023個檔案編號。在oracle8 之前的版本的資料庫中,rowid是受限的,只包括 file# /block# /row# ,則資料庫最多隻允許1023個檔案。

而oracle8開始rowid 包括 data_object_id# / rfile# /block# /rowid# 。data object id 的引入,同時支援了表分割槽的概念,乙個表可以擁有多個分割槽(segment),而乙個分割槽可以在不同的表空間中(由rfile# 表示在segment對應的表空間中對應的 相對檔案編號)。這樣表的容量也增大了。 擴充套件的rowid使得oracle不再侷限於資料檔案只能有1023個的限制,而乙個表可以分割槽,也使得表的容量不再侷限於單個表空間中(1023個檔案 的限制)。

當然,你或許要問,為什麼oracle不調整rowid中表示 file# 的 bit數量,這個應該是由於相容性的引起的,在 oracle7 的索引中儲存的rowid就是 file# + block# + row# ,,因為這樣處理後關於索引的儲存,oracle8和oracle7沒有發生變化(在oracle8中乙個索引(可能分割槽)segment肯定對應了乙個 表(可能分割槽)的segment,這個可以由資料字典關係得到,從而確立了 索引中的rowid 對應哪個 表空間中的資料檔案),在公升級的時候就不用關心 索引的問題,而直接公升級oracle軟體以及執行相關的包,否則將會大動干戈解決索引的問題。這就是oracle實現物理檔案公升級的基礎。

三.rowid舉例

1.建立一臨時表

create table test_rowid (id number, row_id rowid);

2.插入一行記錄

insert into test_rowid values(1,null);

3.修改剛插入的記錄

update test_rowid set row_id = rowid where id = 1;

4.檢視rowid

select rowid,row_id from test_rowid;

返回結果為:

rowid row_id

aaao0daajaaaamyaaa aaao0daajaaaamyaaa

oracle的物理擴充套件rowid有18位,每位採用64位編碼,分別用a~z、a~z、0~9、+、/共64個字元表示。a表示0,b表示1,……z表示25,a表示26,……z表示51,0表示52,……,9表示61,+表示62,/表示63。

rowid具體劃分可以分為4部分。

(1).oooooo:前6位表示data object number,將起轉化位數字後匹配dba_objects中的data_object_id,可以確定表資訊。

如上面例子中的data object number是aaao0d,轉化位數字是14×64×64 +52×64 + 3。

輸入以下查詢:

select owner, object_name from dba_objects where data_object_id = 14*64*64 + 52*64 + 3;

返回:owner object_name

wg test_rowid

(2)fff:第7到9位表示相對表空間的資料檔案號。

上面的例子中是aaj,表示資料檔案9。

輸入以下查詢:

(3).bbbbbb:第10到15位表示這條記錄在資料檔案中的第幾個block中。

上面的例子是aaaamy,轉化位數字是12×64+24,表示這條記錄在資料檔案中的第792個block。

(4).rrr:最後3位表示這條記錄是block中的第幾條記錄。

上面的例子是aaa,表示第0條記錄(總是從0開始計數)。

四.參考資料

1. oracle rowid

2. oracle基本資料型別儲存格式**(四)——rowid型別(一)

3. oracle資料檔案為什麼存在 rfile# and file#

Oracle中查詢rownum和rowid的區別

在查詢中,我們可以注意到,類似於 select xx from table where rownum n n 1 這樣的查詢是有正確含義的,而 select xx from table where rownum n 這樣的查詢只在n 1的時候成立,select xx from table where...

Oracle中查詢rownum和rowid的區別

在查詢中,我們可以注意到,類似於 select xx from table where rownum n n 1 這樣的查詢是有正確含義的,而 select xx from table where rownum n 這樣的查詢只在n 1的時候成立,select xx from table where...

Oracle中查詢rownum和rowid的區別

在查詢中,我們可以注意到,類似於 select xx from table where rownum n n 1 這樣的查詢是有正確含義的,而 select xx from table where rownum n 這樣的查詢只在n 1的時候成立,select xx from table where...