テーブルが挿入されるだけの場合、ROWID
がシーケンシャルまたは昇順であると想定するのはどの程度安全ですか?なぜ?
参照として使用するシーケンスまたは日付の列がないテーブルに新しいレコードが追加されたかどうかを確認する必要がある状況がありました。最近追加されたレコードのROWID
が問題のすべてのレコードよりも高いことがわかりました。したがって、私はそれらが参照レコードよりも古いと想定しました。しかしネットを見回すと、ROWID
に関するいくつかの混合情報があるようです。ROWID
が定数であることが保証されていないとさえ主張する人もいます!
ROWID
の順序に依存することはおそらく良い考えではないことを知っていますが、それによって、ROWID
ステートメントが使用されている場合と挿入のみの場合の両方で、DELETE
値の順序とバリエーションに関してどのような保証が提供されるかを考えました。これらの点を詳述したオラクルの公式文書はありますか?また、ROWID
はテーブルレベルまたはデータベースレベルで一意ですか?
ROWID
sのシーケンスについては、基本的に保証はありません。
ROWID疑似列 ドキュメントから:
行を削除すると、OracleはそのROWIDを後で挿入される新しい行に再割り当てする場合があります。
したがって、delete
シナリオは、連続しない可能性があります。 ROWID
は、相対ファイル番号とブロック番号をエンコードします。新しいエクステントがテーブルに割り当てられたときにこれらが「増加する」という保証はありません。そのため、別のファイルまたはファイルの先頭に近いブロックに割り当てられた場合(たとえば、他の場合)ブロックを解放しました)。
move
(テーブルまたはパーティション)のようなものはすべてROWID
sを変更することにも注意してください(行は少なくともブロックを変更する可能性が高いため)。更新時にパーティション間で行を移行すると、ROWID
sも変更されます。 (ROWID
sおそらくは、IOSでもブロック分割のために安定していません。ただし、それがどのように処理されるかは完全にはわかりません。)
最後の質問については、Oracleドキュメントの同じページから:
通常、rowid値はデータベース内の行を一意に識別します。ただし、同じクラスタに一緒に格納される異なるテーブルの行は、同じROWIDを持つことができます。
いいえ。シングルユーザーモードですべての行のサイズがまったく同じである場合は、そのとおりです。行が特定のブロックに収まらないために収まらない状況を想像してみてください。したがって、この行は「次の」ブロックに配置されます。次に、いくつかの小さい行を挿入します。これは前のブロックに配置されます。
ほとんどの場合、全表スキャンを実行すると、行は書き込まれたのと同じ順序で読み取られますが、例外があり、データベースによる保証はありません。
PS:ROWIDには、ファイル番号、ブロックID、およびブロック内の行オフセットが含まれます。