【问题标题】:How does order by row id work in Oracle?按行 ID 排序如何在 Oracle 中工作?
【发布时间】:2016-04-17 00:16:54
【问题描述】:

我有一个名为 points 的表。我执行了以下查询,并期望得到一个按字典顺序排序的 ROWID 列表,但这并没有发生。 Order by rowid 如何对行进行排序?

select rowid from points order by rowid

我有像下面这样的行

  1. AAAE6MAAFAAABiSAAA
  2. AAAE6MAAFAAABi+AAA

第二行在字典上小于第一行。那么,如果不是字典排序,那么排序标准是什么?

【问题讨论】:

  • 它是一个伪列。没有排序标准,因此您不应依赖这些 ID。此外,例如,如果您移动桌子,这些 ID 可能会发生变化。 docs.oracle.com/cd/B19306_01/server.102/b14200/…
  • 第二个断言并不完全正确。 2nd row is lexicographicaly smaller than first row. 对于 oracle 数据库,它将取决于一些 NLS 数据库设置。
  • 基本上你不应该使用rowid 来订购,我想不出任何可能的场景对rowid 订购有用
  • 当然,在某些情况下按 ROWID 排序很有用。如果您没有唯一键并且您仍然需要确定性顺序。出于同样的原因,Oracle 在非唯一索引内部按 ROWID 排序。

标签: sql oracle rowid


【解决方案1】:

为什么你看到只是用于显示目的的表示。

实际的rowid包含数据块的二进制信息、块中的行、块所在的文件以及表的内部对象id(See the manual for details

当您使用order by rowid 时,Oracle 根据该(内部)信息对行进行排序,而不是基于“字符串表示”。

如果您将查询更改为:

select rowid, 
       dbms_rowid.rowid_relative_fno(rowid) as rel_fno,
       dbms_rowid.rowid_row_number(rowid) as row_num,
       dbms_rowid.rowid_block_number(rowid) as block_num, 
       dbms_rowid.rowid_object(rowid)
from points 
order by rowid

您很可能会看到行号排序背后的逻辑。

请注意,dbms_rowid.rowid_object() 的值将始终相同。如果您的表中只有两行,那么两者很可能也具有相同的 rowid_block_number()

【讨论】:

  • 我正在保存我对答案的投票,以便以后尝试追求金牌徽章,但我忍不住不投票给这个非常详细的答案! :)
  • 这是一个非常好的答案。但是,您知道为什么字符串表示不保留原始顺序吗?做出这样的字符串表示应该不难。
  • @GordonLinoff:对不起,没有主意。我字符串表示只是连接十六进制值 - 但可能与用于比较的单个元素的顺序不同。
  • 它是base-64编码字节的串联(对象ID,[小文件表空间的文件号],块号,记录偏移量)
【解决方案2】:

rowid 的顺序不保证。这取决于您如何设置 NLS 设置。 rowid 还表示数据库中行的物理分配。 rowid 被认为是不可变的(不会更改),但是如果您删除一行并再次插入它,那么它会更改。

如果删除一行,Oracle 可能会将其 rowid 重新分配给新行 稍后插入。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-04
    • 1970-01-01
    • 2018-07-09
    • 1970-01-01
    • 2013-03-30
    • 1970-01-01
    • 2023-04-07
    相关资源
    最近更新 更多