oracle rowID切片,Oracle中的rowid
ROWID是ORACLE中的一個(gè)重要的概念。用于定位數(shù)據(jù)庫(kù)中一條記錄的一個(gè)相對(duì)唯一地址值。通常情況下,該值在該行數(shù)據(jù)插入到數(shù)據(jù)庫(kù)表時(shí)即被確定且唯一。ROWID它是一個(gè)偽列,它并不實(shí)際存在于表中。它是ORACLE在讀取表中數(shù)據(jù)行時(shí),根據(jù)每一行數(shù)據(jù)的物理地址信息編碼而成的一個(gè)偽列。所以根據(jù)一行數(shù)據(jù)的ROWID能找到一行數(shù)據(jù)的物理地址信息。從而快速地定位到數(shù)據(jù)行。數(shù)據(jù)庫(kù)的大多數(shù)操作都是通過ROWID來完成的,而且使用ROWID來進(jìn)行單記錄定位速度是最快的。
要理解索引,必須先搞清楚ROWID。
B-Tree索引的每個(gè)索引條目具有兩個(gè)字段。第一個(gè)字段表示索引的鍵值,對(duì)于單列索引來說是一個(gè)值;而對(duì)于多列索引來說則是多個(gè)值組合在一起的。第二個(gè)字段表示鍵值所對(duì)應(yīng)的記錄行的ROWID。所以索引能加快查詢速度!
索引值→ROWID->將ROWID換算成一行數(shù)據(jù)的物理地址->得到一行數(shù)據(jù)
一、ROWID的格式:
第一部分6位表示:該行數(shù)據(jù)所在的數(shù)據(jù)對(duì)象的 data_object_id;
第二部分3位表示:該行數(shù)據(jù)所在的相對(duì)數(shù)據(jù)文件的id;
第三部分6位表示:該數(shù)據(jù)行所在的數(shù)據(jù)塊的編號(hào);
第四部分3位表示:該行數(shù)據(jù)的行的編號(hào);
索引就是保存了rowid后三個(gè)部分的信息。索引是物理存在的,而rowid是偽列。所以索引可以用來快速地定位到數(shù)據(jù)行。
data_object_id
下面以SAKILA數(shù)據(jù)庫(kù)的ACTOR表為例
這里我們要注意將 data_object_id與 object_id區(qū)分開來,前者是oracle為它的每一個(gè)對(duì)象唯一分配的id,而后者與表ACTOR對(duì)應(yīng)的“段”有關(guān),是存放表tt的段的id,也就是與存放表tt中數(shù)據(jù)的物理位置有關(guān):
select owner,object_id,data_object_id,status from dba_objects where object_name='ACTOR';
alter tableACTOR move tablespace users;select owner,object_id,data_object_id,status from dba_objects where object_name='ACTOR';
我們看到當(dāng)表ACTOR move到了users表空間時(shí),段發(fā)生了改變,物理位置發(fā)生了變化,從而 DATA_OBJECT_ID也發(fā)生了變化。我們知道表是存放在“表段”中的,索引是存放在“索引段”中的。DATA_OBJECT_ID就是表示存放數(shù)據(jù)的“數(shù)據(jù)段對(duì)象的id”
相對(duì)文件編碼
關(guān)于相對(duì)文件編碼和絕對(duì)文件編號(hào):相對(duì)文件id是指相對(duì)于表空間,在表空間唯一,絕對(duì)文件是指相當(dāng)于全局?jǐn)?shù)據(jù)庫(kù)而言的,全局唯一;
select file_name,file_id,relative_fno from dba_data_files;
rowid采用64進(jìn)制來編碼
編碼方法是:A~Z表示0到25;a~z表示26到51;0~9表示52到61;+表示62;/表示63;剛好64個(gè)字符。
Base64編碼表
碼值
字符
碼值
字符
碼值
字符
碼值
字符
0
A
16
Q
32
g
48
w
1
B
17
R
33
h
49
x
2
C
18
S
34
i
50
y
3
D
19
T
35
j
51
z
4
E
20
U
36
k
52
0
5
F
21
V
37
l
53
1
6
G
22
W
38
m
54
2
7
H
23
X
39
n
55
3
8
I
24
Y
40
o
56
4
9
J
25
Z
41
p
57
5
10
K
26
a
42
q
58
6
11
L
27
b
43
r
59
7
12
M
28
c
44
s
60
8
13
N
29
d
45
t
61
9
14
O
30
e
46
u
62
+
15
P
31
f
47
v
63
/
二、使用rowid訪問數(shù)據(jù)的執(zhí)行計(jì)劃
SELECT t.*, ''||t.ROWID FROM "SAKILA"."ACTOR" t;
EXPLAIN PLAN FOR
select * FROM ACTOR where rowid='AAAYEVAAJAAAACrAAA';select * from table(DBMS_XPLAN.DISPLAY)
三、例子:如何從rowid計(jì)算得到obj#,rfile#,block#,row#
我們演示一下具體的計(jì)算方法:
SELECT t.*, ''||t.ROWID FROM "SAKILA"."ACTOR" t;
表sakila的 data_object_id 為 AAAYEVAAJAAAACrAAA的前6位:AAAYEV,那么我們來計(jì)算一下 AAAYEV的值到底是多少:
查詢Base64編碼表
碼值
字符
0
A
24
Y
4
E
21
V
select 24 * 64 * 64 + 4 * 64 + 21 from dual;
AAAYEV=24 * 64 * 64 + 4 * 64 + 21=98581
然后我們查詢字典表,看兩種方法得到的值是否相等:
select owner,object_id,data_object_id,status from dba_objects where object_name='ACTOR';
我們看到通過rowid計(jì)算得到的data_object_id和通過字典表查到的值相等!
表ACTOR的相對(duì)文件編號(hào)為 AAAYEVAAJAAAACrAAA的中的 AAJ,顯然查表可知 AAJ= 9;
我們?cè)谠賮聿樵冏值浔?#xff1a;
可以看到字典表顯示relative_fno為9的數(shù)據(jù)文件為C:\APP\ORACLE\ORADATA\ORCL\PDBORCL\SAMPLE_SCHEMA_USERS01.DBF
查詢當(dāng)前數(shù)據(jù)庫(kù)中的users表空間和對(duì)應(yīng)的數(shù)據(jù)文件
select file_name,tablespace_name from dba_data_files;
兩者結(jié)果一致。
而我們前面執(zhí)行過:alter table ACTOR move tablespace users;所以兩種方式得到的結(jié)果是一致的。
表ACTOR中的第一行數(shù)據(jù)存放的block的編號(hào)為 AAAYEVAAJAAAACrAAA中的 AAAACr,而AAAACr =2*64+43=171
表ACTOR中的第一行數(shù)據(jù)存放的行的編號(hào)為AAAYEVAAJAAAACrAAA中的 AAA,顯然值為0,即第一行。
我們也可以通過Oracle提供的存儲(chǔ)過程來計(jì)算出上面的值:
SELECTdbms_rowid.rowid_object (ROWID) data_object_id,
dbms_rowid.rowid_relative_fno (ROWID) relative_fno,
dbms_rowid.rowid_block_number (ROWID) block_no,
dbms_rowid.rowid_row_number (ROWID) row_noFROMACTOR;
顯然這個(gè)結(jié)果和我們手動(dòng)計(jì)算的結(jié)果是一致的。
參考
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的oracle rowID切片,Oracle中的rowid的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php7.1 aes 加密解密,PHP7
- 下一篇: oracle的多线程怎么实现,创建线程的