什么是rowid?

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> 什么是rowid?

预计阅读时间: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,可以直接定位,一条记录的物理位置,保存rowid需要10个字节或者是80个位二进制位。这80个二进制位分别是:

  • 数据对象编号,表明此行所属的数据库对象的编号,每个数据对象在数据库建立的时候都被唯一分配一个编号,并且此编号唯一。数据对象编号占用大约32位。
  • 对应文件编号,即行所在的数据文件(第一个文件是1),相对于表空间的文件号,表空间的每一个文件编号都是唯一的。文件编号所占用的位置是10位。
  • 行所在数据文件的数据块,表明该行所在文件的块的位置块编号需要22位。
  • 数据块中行的位置(第一行是0),表明该行在行目录中的具体位置行编号需要16位。
  • 对应文件编号,即行所在的数据文件(第一个文件是1),相对于表空间的文件号,表空间的每一个文件编号都是唯一的。文件编号所占用的位置是10位。

    数据块中行的位置(第一行是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编码,分别用AZ、az、0~9、+、/共64个字符表示,“AAAEvwAANAAAACGACL“,可以分为四部分,

  • AAAEvw-数据库对象编号,表示data object id,根据object id可以确定segment。
  • AAN-文件编号,注意这里是相对文件号。根据该相对文件号可以得到绝对文件号,从而确定datafile。
  • AAAACG-块编号,注意他指的是相对于datafile的data block number编号,而不是相对于tablespace的编号。
  • ACL-块编号,即row number。
  • 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名称的由来。
    什么是rowid?

    什么是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;

    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的个人杂货铺,

    什么是rowid?
    本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

    本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

    原文链接:blog.ouyangsihai.cn >> 什么是rowid?


      转载请注明: 好好学java 什么是rowid?

     上一篇
    《Oracle Concept》前言介绍-6 《Oracle Concept》前言介绍-6
    预计阅读时间:5分钟 背景: 按照《Oracle Conecpt》的结构一起了解Oracle。 历史文章: 《》 《》 《》 《》 《》 《》 《》 作为《Concept》的前言,有六个主题,可以说是整本书的缩略,About Relatio
    下一篇 
    探究外键为何要建索引? 探究外键为何要建索引?
    预计阅读时间:22分钟 即将上线的一个新系统,性能测试的时候,一些操作非常慢,经过分析,发现有些SQL检索的条件,未建索引,而且这些字段是表的外键,加了索引,除了会提高这条SQL执行效率外,还会解决一些隐藏的问题,比如表级锁,其实《Orac