oracle學習總結(一)—ROWID

來源:互聯網
上載者:User
文章目錄
  • oracle學習總結(一)---ROWID
oracle學習總結(一)---ROWID

       搞oracle都會經常碰到rowid,本文是筆者根據網上各位大蝦的文章,加上自己學習中的體會,總結而成。
一.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實現物理檔案升級的基礎。

        當 然,真正升級的時候,一些資料檔案頭的 rfile# 需要發生變化,這也是有檔案的一些儲存的特性決定的,為了不和oracle8的格式發生衝突,才需要修改。這個修改代價非常的小,所以oracle選擇了 這個方案。詳細的資訊,大家可以去參考metalink相關內容,有詳細的  儲存(byte 中位元組位)的變化關係。

三.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基礎資料型別 (Elementary Data Type)儲存格式淺析(四)——ROWID類型(一)
3.oracle資料檔案為什麼存在 Rfile# and file#

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.