ROWID

一、12c 官档

  • Books → Concepts → Glossary → rowid
  • Books → SQL Language Reference → 3 Pseudocolumns → 3.8 ROWID Pseudocolumn
  • Books → SQL Language Reference → 2 Basic Elements of Oracle SQL → 2.1 Data Types → 2.1.2 Rowid Data Types
  • Books → PL/SQL Packages and Types Reference → 139 DBMS_ROWID

二、分类

ROWID类型分为两类

  • RESTRICTED—restricted ROWID
  • EXTENDED—extended ROWID:Extended ROWIDs 被用于 8.Xi 或更高版本中

三、定义

数据库中行数据的全局唯一地址

对于数据库中的每一行,ROWID伪列返回行的地址。Oracle数据库rowid值包含定位一行所需的信息:

  • Object No.(32 bit):对象的数据对象号。
  • Block No.(22 bit):数据文件中,行数据驻留的数据块。
  • Row No.(16 bit):数据块中行的位置(第一行为0)
  • File No.(10 bit):行驻留的数据文件(第一个文件是1)。文件编号与表空间相对。

通常,一个rowid值唯一标识数据库中的行。然而,在不同的数据表,存储在同一个集群的行可以有相同的rowid。
ROWID伪列的值的数据类型为ROWID或UROWID。查看 Rowid Data Types 和 UROWID Data Type 了解更多内容。

ROWID值有很多重要的用途:

  • 它们可以最快的定位一条数据
  • 它们可以展示行在表中是如何存储的
  • 它们是行在表中唯一标识。

你不应该使用ROWID作为表的主键。如果你使用导入导出工具删除并重新插入行,例如,那么其rowid可以改变。如果你删除一行,然后Oracle可能重新分配该rowid给新插入的行。

虽然你可以使用ROWID伪列在SELECT和WHERE子句中,这些虚拟列值不存储在数据库中。你不能插入、更新或删除ROWID伪列的值。

实例: 

SELECT ROWID, last_name
  FROM employees
 WHERE department_id = 20;

四、相关的数据类

型数据库中的每一行都有一个地址。下面的部分描述了Oracle数据库中的两种行地址。

1 ROWID Data Type

在Oracle数据库中本地组织的表中的行有称为rowids的行地址。您可以通过查询伪列rowid来检查rowid行地址。这个伪列的值是表示每一行地址的字符串。这些字符串有数据类型ROWID。您还可以创建包含有ROWID数据类型的实际列的表和集群。Oracle数据库不能保证这些列的值是有效的rowids。有关ROWID伪列的更多信息,请参考伪列。

Rowids包含以下信息:

  • 数据文件中包含行的数据块。这个字符串的长度取决于操作系统。
  • 数据块中的行。
  • 包含该行的数据库文件。第一个数据文件的编号为1。这个字符串的长度取决于操作系统。
  • 数据对象号,它是分配给每个数据库段的标识号。您可以从数据字典中检索数据对象数据,查看USER_OBJECTS、DBA_OBJECTS和ALL_OBJECTS。对象共享相同的段(例如,同一簇中的簇表)具有相同的对象编号。

Rowids被存储为base 64值,该值可以包含字符A-Z、A-Z、0-9和加号(+)和正斜杠(/)。Rowids不能直接使用。您可以使用所提供的包DBMS_ROWID来解释rowid内容。包函数提取并提供了上面列出的四个rowid元素的信息。
See Also:

  • 《Oracle Database PL/SQL Packages and Types Reference》:有关DBMS_ROWID包可用的函数的信息以及如何使用它们。

2 UROWID Data Type

某些表的行有非物理或永久的地址,或者不是由Oracle数据库生成的。例如,索引组织的表的行地址存储在索引叶子中,它可以移动。外部表的Rowids(例如通过网关访问的DB2表)不是标准的Oracle Rowids。

Oracle使用通用的rowids (urowids)来存储索引组织和外部表的地址。索引组织表有逻辑的urowids,外部表有外部的urowids。这两种类型的urowids都存储在ROWID伪列中(就像heap组织的表的物理ROWID)。

Oracle根据表的主键创建逻辑rowids。只要主键不变,逻辑rowids就不会改变。索引组织表的ROWID伪列有一个数据类型的UROWID。您可以访问这个伪列,因为您可以使用一个heap组织表的ROWID伪列(使用SELECT…ROWID语句)。如果您想要存储一个索引组织的表的rowids,那么您可以为表一列定义类型为UROWID,并将ROWID伪列的值检索到该列中。

五、查询(DBMS_ROWID)

  • ROWID_BLOCK_NUMBER:通过rowid提取数据块编号
    • row_id(IN):rowid
    • ts_type_in(IN):表空间类型,BIGFILE:大文件表空间,SMALLFILE:传统表空间
  • ROWID_CREATE:根据给定参数返回一个rowid
    • rowid_type(IN):rowid类型,0:restricted,1:extended
    • object_number(IN):对象id
    • relative_fno(IN):关联文件
    • block_number(IN):数据块id
    • row_number(IN):行号
  • ROWID_INFO:根据rowid返回相关参数
    • rowid_in(IN):rowid
    • rowid_type(OUT):rowid类型
    • object_number(OUT):对象id
    • relative_fno(OUT):相关文件
    • block_number(OUT):数据块id
    • row_number(OUT):行号
    • ts_type_in(IN):表空间类型,BIGFILE:大文件表空间,SMALLFILE:传统表空间
  • ROWID_OBJECT:通过rowid提取对象编号
    • row_id IN:rowid
  • ROWID_RELATIVE_FNO:通过rowid提取相关文件编号
    • row_id(IN):rowid
    • ts_type_in(IN):表空间类型,BIGFILE:大文件表空间,SMALLFILE:传统表空间
  • ROWID_ROW_NUMBER:通过rowid提取行号。
    • row_id(IN):rowid
  • ROWID_TO_ABSOLUTE_FNO:通过rowid和给定表,提取相关文件编号。
    • row_id(IN):rowid
    • schema_name(IN):拥有者
    • object_name(IN):对象名
  • ROWID_TO_EXTENDED:转换一个restricted rowid为一个extended rowid。
    如果原始的rowid存储在列中,转换的 就是internal类型;
    如果原始的rowid是以字符串形式存储的,那转换的就是external类型
    • old_rowid(IN):rowid
    • schema_name(IN):拥有者
    • object_name(IN):对象名
    • conversion_type(IN):转换类型
      0:转换restricted internal rowid为extended格式
      1:转换restricted external rowid为extended格式
  • ROWID_TO_RESTRICTED:转换一个exteneded的rowid为一个restricted的rowid。
    restricted的rowid格式为BBBBBBB.RRRR.FFFFF,
    BBBBBBB 代表block
    RRRR 代表在block中的行号,从0开始
    FFFFF 代表文件号。
    这个包可以使用rowid或者rowid转换类型(ROWID_CONVERT_INTERNAL (0)和ROWID_CONVERT_EXTERNAL (1))
    • old_rowid(IN):rowid
    • conversion_type(IN):转换类型
      0:转换restricted internal rowid为extended格式
      1:转换restricted external rowid为extended格式
  • ROWID_TYPE:通过rowid返回rowid类型:0 是 restricted, 1 是 extended。
    • row_id(IN):rowid
  • ROWID_VERIFY:验证rowid是否有效。
    • rowid_in(IN):rowid
    • schema_name(IN):拥有者
    • object_name(IN):对象名
    • conversion_type(IN):转换类型
      0:转换restricted internal rowid为extended格式
      1:转换restricted external rowid为extended格式

六:例子

select rowid,employee_id from employees;

ROWID		   EMPLOYEE_ID
------------------ -----------
AAAFfdAAEAAAADNAAA	   100
AAAFfdAAEAAAADNAAB	   101
AAAFfdAAEAAAADNAAC	   102
AAAFfdAAEAAAADNAAD	   103
AAAFfdAAEAAAADNAAE	   104
AAAFfdAAEAAAADNAAF	   105
AAAFfdAAEAAAADNAAG	   106
AAAFfdAAEAAAADNAAH	   107
AAAFfdAAEAAAADNAAI	   108
AAAFfdAAEAAAADNAAJ	   109
AAAFfdAAEAAAADNAAK	   110

DECLARE
    v_rowid_type          NUMBER;
    v_OBJECT_NUMBER       NUMBER;
    v_RELATIVE_FNO        NUMBER;
    v_BLOCK_NUMBERE_FNO   NUMBER;
    v_ROW_NUMBER          NUMBER;
BEGIN
    DBMS_ROWID.rowid_info (
                 rowid_in        => 'AAAFfdAAEAAAADNAAA',
                 rowid_type      => v_rowid_type,
                 object_number   => v_OBJECT_NUMBER,
                 relative_fno    => v_RELATIVE_FNO,
                 block_number    => v_BLOCK_NUMBERE_FNO,
                 ROW_NUMBER      => v_ROW_NUMBER);  --行号从0开始计数
    DBMS_OUTPUT.put_line ('ROWID_TYPE:  ' || TO_CHAR (v_rowid_type));
    DBMS_OUTPUT.put_line ('OBJECT_NUMBER:  ' || TO_CHAR (v_OBJECT_NUMBER));
    DBMS_OUTPUT.put_line ('RELATIVE_FNO:  ' || TO_CHAR (v_RELATIVE_FNO));
    DBMS_OUTPUT.put_line ('BLOCK_NUMBER:  ' || TO_CHAR (v_BLOCK_NUMBERE_FNO));
    DBMS_OUTPUT.put_line ('ROW_NUMBER:  ' || TO_CHAR (v_ROW_NUMBER));
END;
/
ROWID_TYPE:  1
OBJECT_NUMBER:	22493
RELATIVE_FNO:  4
BLOCK_NUMBER:  205
ROW_NUMBER:  0

select dbms_rowid.rowid_object('AAAFfdAAEAAAADNAAA') object_no,---> 32bit object# 
       dbms_rowid.rowid_relative_fno('AAAFfdAAEAAAADNAAA') file_no,---> 10bit rfile# 
       dbms_rowid.rowid_block_number('AAAFfdAAEAAAADNAAA') block_no,---> 22bit block# 
       dbms_rowid.rowid_row_number('AAAFfdAAEAAAADNAAA') row_no---> 16bit row# 
  from dual;
 OBJECT_NO    FILE_NO	BLOCK_NO     ROW_NO
---------- ---------- ---------- ----------
     22493	    4	     205	  0

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值