一、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