rowid(oracle) - 有什么用吗?
题
我的理解是,在查询返回的结果中,ROWID是每行的唯一值。
为什么我们需要这个行列? Oracle中已经有Rownum。
在SQL查询中有任何人使用过ROWID吗?
解决方案
RowID是行的物理位置。因此,这是定位行的最快方法,甚至比主键查找更快。因此,它可以在某些类型的交易中有用 where
DML的条款针对那些相同的行。
Oracle Select ...用于更新语法隐式使用ROWID时,我们使用当前的位置更新锁定行。此外,异常表(在将异常应用于子句中应用约束时引用)具有列row_id。这使我们能够快速识别打破我们约束的行。
后一个示例指出了另一种一般用法:当我们编写一些通用代码并且需要一种机制来存储UID时,而无需担心数据类型,复合键,等等。
另一方面,Rownum是一个伪列,它在给定的结果集中标记一行。它没有永久意义。
编辑
给定记录的ROWID可以在系统的寿命中发生变化,例如通过表重建。另外,如果删除了一个记录,则可以给出新的记录。因此,从长远来看,ROWID不适合用作UID。但是它们足以在交易中使用。
其他提示
我现在知道一个例子。
假设您有没有主键的表。因此,该表可以具有重复的行。您将如何删除重复行,但要准确保留其中之一?
Oracle提供ROWID作为主键的替代品。您可以编写一个相关类型的嵌套查询[((按行中的所有列组组,然后在内部查询中的每个组中占用最小值(rowID),因为每个组在Outerquery中删除组中的另一行)
例子
SQL> select * from employees;
SSN NAME
---------- ----------
1 helen
1 helen
2 helen
2 peter
10 sally
11 null
11 null
12 null
8 rows selected.
SQL> delete from employees where ROWID NOT IN (select min(ROWID) from employees
group by ssn,name);
2 rows deleted.
SQL> select * from employees;
SSN NAME
---------- ----------
1 helen
2 helen
2 peter
10 sally
11 null
12 null
6 rows selected.
请注意,ROWID不会在数据库导出和导入周期中持续存在。您绝不应该将rowID存储在表中作为钥匙值。
rowid唯一地标识表中的一行。 Rownum为您提供特定查询结果的行号。两者非常不同,并且不可互换。
还有Row_number是Rownum的更现代版本,行为略有不同。查看 本文 这解释了差异。
ROWID由(但据我记得,Rownum部分是Rowid的最后一部分,但不一定是按此顺序组成的):
- 对象的独特凹痕器。
- fileno表空间中的数据文件的相对数量。
- blockno文件缩影后的数据文件中的相对块号。
- rownum在块内的相对隆起。
您可以使用RowidtoChar()SQL功能或使用:
SQL> select DBMS_ROWID.ROWID_OBJECT(rowid) "OBJECT",
2 DBMS_ROWID.ROWID_RELATIVE_FNO(rowid) "FILE",
3 DBMS_ROWID.ROWID_BLOCK_NUMBER(rowid) "BLOCK",
4 DBMS_ROWID.ROWID_ROW_NUMBER(rowid) "ROW"
5 from dual
6 /
OBJECT FILE BLOCK ROW
---------- ---------- ---------- ----------
258 1 2082 0
请注意,Rownum(或上述查询中的行)是 不是 与您在SELECT查询中使用的SQL Pseudo列ROWNUM相同,这只是结果集中的行动态生成的rownumber。
请注意,由于这种实现,行,块,扩展和段不可传输,而不会破坏索引无效的rowID。
ROWID是该行所在的块中最直接的访问路径,并唯一地缩进了行,因为它编码了该文件中的唯一文件和唯一块和该块中的唯一行。
更多信息:
看: DBMS注释ROWID格式
笔记:
如果您对Oracle结构数据库文件和块的方式有所了解,并且知道一些C编程,则可以很容易地制作一个程序,以显示RowID给出的块的内容(8K或在此中使用的任何块大小数据库,从fileheadersize + blockno * block_size开始的数据库。该块包含块标头及之后(假设表未群集)rowdir,每行都会在每一行中提供相对偏移。因此,例如在rowdir内的位置0是块内0-行的相对偏移,在rowdir内的位置1处的位置1,1-ST行的相对位置等。行数本身存储在块标头中的某个地方(请参阅块布局上的Orale文档)。
有了一点编程知识,并查找Oracle数据库文件上的文档,以确切的块布局块,您可以看到如何将行存储在磁盘上,甚至重建每个列的行存储的所有值。每一行都包含行的长度和列数的元数据,每一行,对于每列,列的指示列的类型以及值和以下值的值。 Bytesize 0表示列数据为空(或:null)。
ROWID基本上允许您拥有两个与完全相同的数据的行。虽然您通常希望主键比ROWID更有意义,但这只是一种自动确保行之间唯一性的简单方法。