什么是rowid?

>>强大,10k+点赞的 SpringBoot 后台管理系统竟然出了详细教程!
点击标题下「蓝色微信名」可快速关注

预计阅读时间:6分钟


什么是rowid?


上周员工培训,介绍索引的时候,提到了rowid的概念,没有展开来说,这儿我们再来介绍下。


在Oracle中,每张表会有一个伪列,叫做rowid。伪列就像正常的一个表列,但不会实际存储在表中,会单独进行存储,并占用10个字节,用18个字符显示。可以执行SELECT操作,检索rowid,但是不能插入、更新或者删除rowid。伪列很像一个没有参数的SQL函数,使用DESC看不到这张表有rowid列,这个伪列也不会占用空间。


Oracle内部使用rowid来构建索引。像我们常见的B树索引,会包含一个有序的索引键值列表。每个索引键值会关联一个rowid,这个rowid会快速定位到相应行的地址。


rowid有些重要的功能:

  • 使用rowid是最快地访问特定行的方法。

  • 通过rowid可以了解如何构建一张表。

  • rowid是表中行的唯一标识。


上面一直说rowid可快速定位记录,原因就是通过rowid,可以直接定位,一条记录的物理位置,保存rowid需要10个字节或者是80个位二进制位。这80个二进制位分别是:

  • 数据对象编号,表明此行所属的数据库对象的编号,每个数据对象在数据库建立的时候都被唯一分配一个编号,并且此编号唯一。数据对象编号占用大约32位。

  • 对应文件编号,即行所在的数据文件(第一个文件是1),相对于表空间的文件号,表空间的每一个文件编号都是唯一的。文件编号所占用的位置是10位。

  • 行所在数据文件的数据块,表明该行所在文件的块的位置块编号需要22位。

  • 数据块中行的位置(第一行是0),表明该行在行目录中的具体位置行编号需要16位。


知道了以上信息,相当于知道了这条记录,对应的物理位置,因此RBO优化器模式下,认为通过rowid的扫描,是效率最高的访问方式,

什么是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编码,分别用A~Z、a~z、0~9、+、/共64个字符表示,“AAAEvwAANAAAACGACL“,可以分为四部分,

  • AAAEvw-数据库对象编号,表示data object id,根据object id可以确定segment。

  • AAN-文件编号,注意这里是相对文件号。根据该相对文件号可以得到绝对文件号,从而确定datafile。

  • AAAACG-块编号,注意他指的是相对于datafile的data block number编号,而不是相对于tablespace的编号。

  • ACL-块编号,即row number。


P.S. Base64编码说明

Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之后在6位的前面补两个0,形成8位一个字节的形式。 如果剩下的字符不足3个字节,则用0填充,输出字符使用'=',因此编码后输出的文本末尾可能会出现1或2个'='。为了保证所输出的编码位可读字符,Base64制定了一个编码表,以便进行统一转换。编码表的大小为2^6=64,这也是Base64名称的由来。

什么是rowid?


另外,使用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;



如果您觉得本文有帮助,欢迎关注转发:bisal的个人杂货铺,

什么是rowid?