程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle教程 >> OracleROWID詳解

OracleROWID詳解

編輯:Oracle教程

1.ROWID定義

ROWID:數據庫中行的全局唯一地址

對於數據中的每一行,rowid偽列返回行的地址。rowid值主要包含以下信息:

對象的數據對象編號該行所在的數據文件中的數據塊該行中數據塊的位置(第一行是0)數據行所在的數據文件(第一個文件是1)。該文件編號是相對於表空間。

通常來說,一個rowid值唯一標識數據中的一行。然而,存儲在同一聚簇中不同的表可以有相同的rowid。

2.擴展ROWID

從Oracle 8i開始使用擴展rowid標識行物理地址

擴展rowid使用base64編碼行的物理地址,編碼字符包含 A-Z, a-z, 0-9, +, 和 /。

擴展rowid由四部分組成:OOOOOOOFFFBBBBBBRRR:

其中:

OOOOOO:數據對象編號(6位顯示)FFF:相關數據文件編號(3位顯示)BBBBBB:數據塊編號(6位顯示)RRR:數據塊中行編號(3位顯示)

\

 

3.受限ROWID

為了兼容Oracle8i以前的應用使用受限rowid標識行物理地址

受限rowid使用二進制標識行的物理地址,當使用SQL*Plus查詢時,二進制被轉換為VARCHAR2/十六進制顯示。

受限rowid有三部分組成:BBBBBB.RRRR.FFFF(block.row.file):

BBBBBB:數據庫塊編號(6位顯示)RRRR:數據塊找中行編號(4位顯示)FFFF:數據文件編號(4位顯示)

\

4.ROWID內部存儲

對於內部ROWID存儲結構,擴展ROWID在大多數平台上采用10個字節存儲,受限ROWID6個字節存儲。具體規則如下:

數據對象編號-----32bit數據文件編號------10bit數據塊編號--------22bit數據塊中行編號----16bit

Oracle 8i以前,rowid占用6個字節空間,分別是22bit的block#,16bit的row#,10bit的file#。

從Oracle 8i開始,rowid占用10個字節空間,分別是32bit的object#,10bit的rfile#,22bit的block#,16bit的row#。新增了32bit的object#。受限rowid的file#t基於整個數據庫,擴展rowid的rfile#基於表空間。

5.base 64編碼

索引

對應字符

索引

對應字符

索引

對應字符

索引

對應字符

0

A

17

R

34

i

51

z

1

B

18

S

35

l

52

0

2

C

19

T

36

k

53

1

3

D

20

U

37

l

54

2

4

E

21

V

38

m

55

3

5

F

22

W

39

n

56

4

6

G

23

X

40

o

57

5

7

H

24

Y

41

p

58

6

8

I

25

Z

42

q

59

7

9

J

26

a

43

r

60

8

10

K

27

b

44

s

61

9

11

L

28

c

45

t

62

+

12

M

29

d

46

u

63

/

13

N

30

e

47

v

 

 

14

O

31

f

48

w

 

 

15

P

32

g

49

x

 

 

16

Q

33

h

50

y

 

 

6.Example

創建my_rowid表,通過對my_rowid表的操作來解讀rowid。

SQL> create table my_rowid(id number,name varchar2(50));

Table created

--插入兩行數據

SQL> insert into my_rowid values(1,'whz');

1 row inserted

SQL> insert into my_rowid values(2,'chiclewu');

1 row inserted

6.1查看my_rowid表中行的ROWID

SQL> select rowid,id,name from my_rowid;

ROWID ID NAME
------------------ ---------- --------------------------------------------------
AAATLnAAFAAAAD9AAA 1 whz
AAATLnAAFAAAAD9AAB 2 chiclewu

6.2 ROWID組成格式

SQL> select rowid,
2 substr(rowid, 1, 6) "#objct",
3 substr(rowid, 7, 3) "#file",
4 substr(rowid, 10, 6) "#block",
5 substr(rowid, 16, 3) "#row"
6 from my_rowid;

ROWID #objct #file #block #row
------------------ ------------ ------ ------------ ------
AAATLnAAFAAAAD9AAA AAATLn AAF AAAAD9 AAA
AAATLnAAFAAAAD9AAB AAATLn AAF AAAAD9 AAB

將base64編碼轉換為十進制:

#object:AAATLn -----> 0 0 0 19 11 39(顯示字符對應的索引) ----->0*64^5+0*64^4+0*64^3+ 19*64^2+11*64^1+39*64^1 =78567

以此類推,得出:

#file:AAF----------> 5

#block:AAAAD9------> 253

#row:AAA-----------> 0

使用dbms_rowid包獲取my_rowid表的信息:

SQL> select rowid,
2 dbms_rowid.rowid_object(rowid) "#objct",
3 dbms_rowid.rowid_relative_fno(rowid) "#file",
4 dbms_rowid.rowid_block_number(rowid) "#block",
5 dbms_rowid.rowid_row_number(rowid) "#row"
6 from my_rowid;

ROWID #objct #file #block #row
------------------ ---------- ---------- ---------- ----------
AAATLnAAFAAAAD9AAA 78567 5 253 0
AAATLnAAFAAAAD9AAB 78567 5 253 1

結論:與base64直接轉換的一樣,說明#block顯示6為,#rfile顯示3位,#block顯示6位,#row顯示3位是對的。

6.3 DUMP函數轉換ROWID

為了驗證rowid的存儲空間為10字節,其中32bit的object#,10bit的rfile#,22bit的block#,16bit的row#。我們需要使用dump函數。

SQL> select rowid,dump(rowid,16) from my_rowid;

ROWID DUMP(ROWID,16)
------------------ --------------------------------------------------------------------------------
AAATLnAAFAAAAD9AAA Typ=69 Len=10: 0,1,32,e7,1,40,0,fd,0,0
AAATLnAAFAAAAD9AAB Typ=69 Len=10: 0,1,32,e7,1,40,0,fd,0,1

其中,len=10表示是個字節。

AAATLnAAFAAAAD9AAA-->0,1,32,e7,1,40,0,fd,0,0

將十六進制轉換為二進制:

0----->00000000

1----->00000001

32---->00110010

e7---->11100111

1----->00000001

40--->01000000

0---->00000000

df--->11011111

0---->0000000

0---->0000000

組合為80bit的rowid:
rowid=00000000000000010011001011100111 0000000101 0000000000000011111101 00000000000000=78567 925 253 0

結論:dump函數轉換rowid後,按照32bit的object#,10bit的rfile#,22bit的block#,16bit的row#劃分後結果與dbms_rowid包和base64編碼的值相等,說明我測試的平台上rowid是按照10個字節存儲的,並且每個內部劃分也是正確的。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved