4

我正在查看一个客户端应用程序,它检索包括 在内的多个列ROWID,然后用于ROWID识别需要更新的行:

update some_table t set col1=value1
where t.rowid = :selected_rowid

这样做安全吗?随着表被修改,ROWID行可以改变吗?

4

3 回答 3

7

“从 Oracle 8 开始,ROWID格式和大小从 8 个字节更改为 10 个字节。请注意,ROWID当您重新组织或导出/导入表时, 's 会发生变化。对于分区表,如果行从一个分区迁移到另一个分区,它也会发生变化一个UPDATE。”

http://www.orafaq.com/wiki/ROWID

我会说不。这可能是安全的,例如应用程序ROWID临时存储(比如生成一个可选项目列表,每个项目都用 标识ROWID,但该列表会定期重新生成而不是存储)。但是,如果ROWID以任何持久的方式使用它是不安全的。

于 2012-07-20T20:12:46.377 回答
6

假设您使用它ROWID之后的一小段时间SELECT,该表是一个标准的堆组织表,并且 DBA 没有对表做任何事情(如果应用程序在线,这是一个相当安全的假设),ROWID将是稳定的。最好使用主键,但是当主键不可用时,大量 Oracle 开发的工具和框架将在ROWID短时间内使用主键。如果你打算在ROWID你之后使用很长一段时间,那将是不安全的SELECT——例如,如果你允许用户在本地编辑数据,然后在一段时间后与主数据库同步。

ROWID只是一行的物理位置,所以任何导致该位置改变的东西都会改变ROWID.

  • 如果您使用的是索引组织表或分区表,则对行的更新可能会更改行的物理位置,这将更改ROWID.
  • 如果从堆组织的表中删除一行,后续INSERT可能会插入具有完全不同数据的数据,而这些数据恰好使用与ROWID之前删除的行相同的数据。
  • 各种管理任务可能会导致ROWID更改。导出和导入表会改变ROWID例如,但是会做一些类似新的在线收缩命令的事情。然而,这些管理任务通常不会在应用程序启动时完成,而且几乎肯定不会在白天完成。但是,如果 DBA 执行此类操作时应用程序没有关闭,或者应用程序保留数据,则可能会导致问题。

ROWID随着时间的推移,新特性为s 带来改变的新可能性变得越来越普遍。例如,索引组织表和在线收缩选项是相对较新的功能。在未来,可能会有更多的特性至少涉及ROWID到改变的可能性。

当然,如果我们是迂腐的,那么依赖主键也是不安全的。完全有可能出现其他会话并在您读取该行后更新该行的主键,或者某个其他会话在您选择该行并插入具有相同数据和不同主键的新行后删除该行。在任何一种情况下,了解使用数据库的应用程序实际应该做什么都是有帮助的。例如,允许更新主键或重用主键是非常罕见的,因此您通常可以确定使用主键是安全的。同样,相对常见的结论是,鉴于您使用分区的方式或给定您在索引组织表中定义索引的方式,更新将不会ROWID. 例如,如果您知道表是由 分区的LOAD_DATE,并且您从不更新LOAD_DATE,那么您实际上不会ROWID因为更新而经历对 的更改。如果您知道该表是按索引组织的,但您没有更新属于该索引的列,ROWIDUPDATE.

于 2012-07-20T20:23:06.930 回答
4

我认为这样做并不安全,理论上它不会改变,当然,直到有人“意外”删除了实际数据库中的某些内容......

我只会使用PK更有意义。

于 2012-07-20T20:09:56.307 回答