预计阅读时间:6分钟
上周员工培训,介绍索引的时候,提到了rowid的概念,没有展开来说,这儿我们再来介绍下。
在Oracle中,每张表会有一个伪列,叫做rowid。伪列就像正常的一个表列,但不会实际存储在表中,会单独进行存储,并占用10个字节,用18个字符显示。可以执行SELECT操作,检索rowid,但是不能插入、更新或者删除rowid。伪列很像一个没有参数的SQL函数,使用DESC看不到这张表有rowid列,这个伪列也不会占用空间。
Oracle内部使用rowid来构建索引。像我们常见的B树索引,会包含一个有序的索引键值列表。每个索引键值会关联一个rowid,这个rowid会快速定位到相应行的地址。
rowid有些重要的功能:
通过rowid可以了解如何构建一张表。
上面一直说rowid可快速定位记录,原因就是通过rowid,可以直接定位,一条记录的物理位置,保存rowid需要10个字节或者是80个位二进制位。这80个二进制位分别是:
对应文件编号,即行所在的数据文件(第一个文件是1),相对于表空间的文件号,表空间的每一个文件编号都是唯一的。文件编号所占用的位置是10位。
数据块中行的位置(第一行是0),表明该行在行目录中的具体位置行编号需要16位。
知道了以上信息,相当于知道了这条记录,对应的物理位置,因此RBO优化器模式下,认为通过rowid的扫描,是效率最高的访问方式,
可以用关键字rowid,作为一个列名,检索某行对应的rowid值,如下所示,直接用不行,但可以用”rowid, t“的表示,
SQL select rowid from a where id=1000;
ROWID
------------------
AAAEvwAANAAAACGACL
SQL select rowid, t.* from a t;
ROWID ID
------------------ -------
AAAEvwAANAAAACGACL 1000
返回的是18位字符,每位基于base64编码,分别用AZ、az、0~9、+、/共64个字符表示,“AAAEvwAANAAAACGACL“,可以分为四部分,
AAN-文件编号,注意这里是相对文件号。根据该相对文件号可以得到绝对文件号,从而确定datafile。
ACL-块编号,即row number。
P.S. Base64编码说明
Base64编码要求把3个8位字节(38=24)转化为4个6位的字节(46=24),之后在6位的前面补两个0,形成8位一个字节的形式。 如果剩下的字符不足3个字节,则用0填充,输出字符使用’=’,因此编码后输出的文本末尾可能会出现1或2个’=’。为了保证所输出的编码位可读字符,Base64制定了一个编码表,以便进行统一转换。编码表的大小为2^6=64,这也是Base64名称的由来。
另外,使用dbms_rowid中的函数,可以进行rowid的转换,如下所示,
SQL select dbms_rowid.rowid_relative_fno(rowid) file_no, dbms_rowid.rowid_block_number(rowid) block, dbms_rowid.rowid_row_number(rowid) row_number from a where id = 1000;
FILE_NO BLOCK ROW_NUMBER
---------- ---------- ----------
13 134 139
虽然在Oracle中,dbms_rowid加密了,但使用unwrap工具,可以解密,得到如上三个函数的解释,
函数ROWID_RELATIVE_FNO介绍:
extracts the relative file number from a ROWID.
参数:
row_id - ROWID to be interpreted
ts_type_in - type of tablespace which this row belongs to
函数声明:
function rowid_relative_fno(row_id IN rowid, ts_type_in IN varchar2 default ‘SMALLFILE’) return number;
**函数ROWID_BLOCK_NUMBER介绍**: extracts the block number from a ROWID. **参数**:
row_id - ROWID to be interpreted
ts_type_in - type of tablespace which this row belongs to
**函数声明**: function rowid_block_number(row_id IN rowid, ts_type_in IN varchar2 default 'SMALLFILE') return number;**函数ROWID_ROW_NUMBER介绍**:
extracts the row number from a ROWID.
**参数**:row_id - ROWID to be interpreted
**函数声明**: function rowid_row_number(row_id IN rowid) return number;extracts the relative file number from a ROWID.
row_id - ROWID to be interpreted
函数声明:
extracts the block number from a ROWID.
row_id - ROWID to be interpreted
函数声明:
extracts the row number from a ROWID.
row_id - ROWID to be interpreted
function rowid_row_number(row_id IN rowid) return number;
如果您觉得本文有帮助,欢迎关注转发:bisal的个人杂货铺,