ROWID是数据的详细地址,通过rowid,oracle可以快速的定位某行具体的数据的位置。
ROWID可以分为物理rowid和逻辑rowid两种。普通的堆表中的rowid是物理rowid,索引组织表(IOT)的rowid是逻辑rowid。oracle提供了一种urowid的数据类型,同时支持物理和逻辑rowid。本文主要关注物理rowid
物理rowid又分为扩展rowid(extended rowid)和限制rowid(restricted rowid)两种格式。限制rowid主要是oracle7以前的rowid格式,现在已经不再使用,保留该类型只是为了兼容性。所以本文的提到物理rowid一般是指扩展rowid格式。
本文主要内容:
1.Rowid的显示形式
2.如何从rowid计算得到obj#,rfile#,block#,row#
3.如何从obj#,rfile#,block#,row#计算得到rowid
4.Rowid的内部存储格式
5.Index中存储的rowid
1.Rowid的显示形式
我们从rowid伪列里select出来的rowid是基于base64编码,一共有18位,分为4部分:
OOOOOOFFFBBBBBBRRR
其中:
OOOOOO: 六位表示data object id,根据object id可以确定segment。关于data object id和object id的区别,请参考http://www.orawh.com/index.php/archives/62
FFF: 三位表示相对文件号。根据该相对文件号可以得到绝对文件号,从而确定datafile。关于相对文件号和绝对文件号,请参考http://blog.itpub.net/post/330/22749
BBBBBB:六位表示data block number。这里的data block number是相对于datafile的编号,而不是相对于tablespace的编号。
RRR:三位表示row number。
Oracle提供了dbm_rowid来进行rowid的一些转换计算。
SQL> create table test(id int,name varchar2(30));
Table created.
SQL> insert into test values(1,'a');
1 row created.
SQL> commit;
Commit complete.
SQL> select rowid from test;
ROWID
------------------
AAAGbEAAHAAAAB8AAA
SQL> select dbms_rowid.rowid_object(rowid) obj#,
2 dbms_rowid.rowid_relative_fno(rowid) rfile#,
3 dbms_rowid.rowid_block_number(rowid) block#,
4 dbms_rowid.rowid_row_number(rowid) row#,
5 dbms_rowid.rowid_to_absolute_fno(rowid,'SYS','TEST') file#
6 from test;
OBJ# RFILE# BLOCK# ROW# FILE#
----------- ------------ ------------- ---------- ----------
26308 7 124 0 7
2. 如何从rowid计算得到obj#,rfile#,block#,row#
rowid是base64编码的,用A~Z a~z 0~9 + /共64个字符表示。A表示0,B表示1,……,a表示26,……,0表示52,……,+表示62,/表示63可以将其看做一个64进制的数。
所以,
obj#=AAAGbE=6*64^2+27*64+4=26308
rfile#=AAH=7
block#=AAAAB8=64+60=124
row#=AAA=0
3. 如何从obj#,rfile#,block#,row#计算得到rowid
实际上就是将十进制数转化成64进制数,当然,从二进制转化的规则比较简单点。
将二进制数从右到左,6个bit一组,然后将这6个bit组转成10进制数,就是A~Z a~z 0~9 + /这64个字符的位置(从0开始),替换成base64的字符即可。
obj#=26308=110 011011 000100=6 27 4=G b E,补足成6位base64编码,左边填0,也就是A,结果为AAAGbE
rfile#=7=111=7=H,补足成3位,得到AAH
block#=124=1 111100=1 60=B 8,补足成6位,得到AAAAB8
row#=0,3位AAA
合起来就是AAAGbEAAHAAAAB8AAA
4. Rowid的内部存储格式
虽然我们从rowid伪列中select出来的rowid是以base64字符显示的,但在oracie内部存储的时候还是以原值的二进制表示的。一个扩 展rowid采用10个byte来存储,共80bit,其中obj#32bit,rfile#10bit,block#22bit,row#16bit。所以相对文件号不能超过1023,也就是一个表空间的数据文件不能超过1023个(不存在文件号为0的文件),一个datafile只能有2^22=4M个 block,,一个block中不能超过2^16=64K行数据。而一个数据库内不能有超过2^32=4G个object。
SQL> select dump(rowid,16) from test;
DUMP(ROWID,16)
--------------------------------------------
Typ=69 Len=10: 0,0,66,c4,1,c0,0,7c,0,0
00000000 00000000 01100110 11000100 00000001 11000000 00000000 01111100 00000000 00000000
最右边16bit为row#=00000000 00000000=0
接下来22bit为block#=000000 00000000 01111100=124
接下来10bit为rfile#=00000001 11=7
接下来32bit为obj#=00000000 00000000 01100110 11000100=26308
5. Index中存储的rowid
a. 普通B-tree索引
SQL> create index ix_test on test(id);
Index created.
SQL> select file_id,block_id from dba_extents where segment_name='IX_TEST' and owner=user;
FILE_ID BLOCK_ID
---------- ----------
7 129
---由于是assm表空间,去掉3个block的头
SQL> alter system dump datafile 1 block 132;
System altered.
得到trace文件内容如下(省略无关内容):
row#0[8024] flag: -----, lock: 0
col 0; len 2; (2): c1 02 ---索引键数据ID=1
col 1; len 6; (6): 01 c0 00 7c 00 00 ---对应的rowid记录
----- end of leaf block dump -----
End dump data blocks tsn: 7 file#: 7 minblk 132 maxblk 132
普通索引中保存的rowid是不包括obj#的,但是分区表的global index是包括obj#的,这是因为分区表包括多个segment,每个segment可能在不同的datafile中,根据表的obj#就无法确定该 索引键对应的rowid(rfile#确定不了)。
01 c0 00 7c 00 00 转化为二进制 000000001 11000000 00000000 01111100 00000000 00000000
右边8bit row#=0
接下来22bit block#=000000 00000000 01111100=124
接下来10bit rfile#=000000001 11=7
b.唯一索引
SQL> drop index ix_test;
Index dropped.
SQL> create unique index ix_test on test(id);
Index created.
SQL> select file_id,block_id from dba_extents where segment_name='IX_TEST' and owner=user;
FILE_ID BLOCK_ID
---------- ----------
7 129
SQL> alter system dump datafile 1 block 132;
System altered.
得到trace文件内容如下:
row#0[8025] flag: -----, lock: 0, data:(6): 01 c0 00 7c 00 00 ---对应的rowid记录
col 0; len 2; (2): c1 02 ---索引键数据ID=1
----- end of leaf block dump -----
End dump data blocks tsn: 7 file#: 7 minblk 132 maxblk 132
得到rowid为 01 c0 00 7c 00 00,具体的转换计算和前面的一样,就不重复了。
Base64编码说明
Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之后在6位的前面补两个0,形成8位一个字节的形式。 如果剩下的字符不足3个字节,则用0填充,输出字符使用'=',因此编码后输出的文本末尾可能会出现1或2个'='。
为了保证所输出的编码位可读字符,Base64制定了一个编码表,以便进行统一转换。编码表的大小为2^6=64,这也是Base64名称的由来。
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 |
/ |
原文链接:http://hi.baidu.com/wwynhm/item/1a376fbc6063b7d084dd79a7
相关推荐
这部分涵盖了Oracle中的约束概念及其管理和使用方法。 - **维护数据完整性**:通过约束保证数据的一致性和准确性。 - **约束**:如主键、外键、唯一性等。 - **使用** - **维护** - **删除约束** - **显示约束...
### ORACLE函数及其用法详解 #### 概述 Oracle是一种广泛使用的数据库管理系统,它提供了丰富的内置函数,这些函数能够帮助开发者和数据库管理员更高效地处理数据。本文将详细介绍Oracle中的一些常用函数及其应用...
oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 第一章 Oracle入门 一、 数据库概述 数据库(Database)是按照数据结构来组织、存储和管理数据的仓库,它产生于距今五十年前。简单来说是本身可视...
- **BOOLEAN**: 在Oracle中,没有直接的布尔数据类型,但可以使用1(TRUE)和0(FALSE)来模拟。 6. **其他数据类型**: - **RAW**: 用于存储原始二进制数据,长度可变。 - **LONG RAW**: 与LONG类似,但用于...
以下是对Oracle中重要表进行逻辑备份的几种方法的详细说明。 1. **物化视图**:物化视图是Oracle数据库提供的一种实现逻辑备份的有效工具,特别是对于需要实时或近乎实时备份的重要表。物化视图可以看作是远程数据...
Oracle.DataAccess.Client.dll是Oracle公司为.NET开发者提供的一个关键组件,它是Oracle数据提供程序的一部分,用于在C#等.NET环境中与Oracle数据库进行交互。这个库包含了丰富的Oracle类和接口,使得开发人员可以...
### 超详细ORACLE培训实例知识点概览 #### 引言 - **SUN与Oracle合并背景...通过以上章节的学习,读者可以全面掌握Oracle数据库的使用方法和技术要点,无论是对于数据库管理员还是开发人员来说,都是非常宝贵的资源。
- RMAN( Recovery Manager):Oracle提供的备份和恢复工具及其使用方法。 - 数据库备份类型:完整备份、增量备份和差异备份的策略。 - 数据库恢复:如何处理数据丢失,使用闪回技术或归档日志恢复。 7. **性能...
10. **Oracle特性支持**:包括Oracle的LOB(Large Object)操作、ROWID访问、触发器、存储过程调用、PL/SQL包的使用等。 综上所述,cx_Oracle-6.1.tar.gz文件是Python开发者连接Oracle数据库的重要工具,通过这个库...
12. 获取rowid并且进行比较:在Oracle数据库中,rowid是每行数据的物理地址,了解和使用rowid可以提高数据处理的效率。 13. 安装sqlplus帮助系统:Sqlplus是Oracle提供的命令行界面工具,帮助系统可以提供SQL命令的...
本文将围绕ROWID的结构与功能、B树索引的理解、索引使用限制及其解决方案、个人调优见解以及具体的优化方法等方面,提供全面而深入的知识点分析。 #### 1. ROWID:Oracle数据库中的定位神器 ROWID是Oracle数据库中...
Oracle SQL调优是数据库...通过以上内容的学习和实践,参与者将具备对Oracle SQL调优的全面理解,能够有效地优化数据库性能,提升系统的稳定性和响应速度。在实际工作中,持续的监控、分析和调整是保持SQL性能的关键。
### ORACLE学习手册和案例知识点总结 #### 一、ORACLE基础知识 ##### 1.1 ORACLE OLAP与OLTP介绍 **1.1.1 什么是OLTP** ...希望读者能够通过本文档对Oracle有一个更全面的认识,并能够在实际工作中运用这些知识。
文档包含了Oracle Data Provider for .NET的关键特性和用法,旨在帮助开发者理解和利用这个工具来构建高性能的Oracle数据库应用程序。 ODP.NET的主要特点包括: 1. **连接性**:ODP.NET提供了对Oracle数据库的直接...
- 解释了连接字符串的使用方法和连接池的概念。 - 涉及了数据库驻留连接池(Database Resident Connection Pooling, DRCP)。 - 还有代理认证、外部认证和特权连接的建立方法。 ### 4. 连接池与安全连接...
- **进行数据库备份:** 使用适当的方法对数据库进行全面备份,以防再次出现类似问题。 **特殊处理:** - **所有控制文件损坏:** 在这种情况下,需要从备份中恢复控制文件或将数据库恢复到最近的一个备份点。 - *...
- **HASH**:提示使用哈希访问方法。 - **ROWID**:直接通过ROWID访问行。 - **FULL**:全表扫描。 - **INDEX**:使用索引访问。 - **INDEX_ASC**、**INDEX_DESC**:分别指定索引升序或降序扫描。 - **NO_INDEX**:...