Rowid(Oracle) - それを使用しますか?
質問
私の理解では、Rowidは、クエリによって返される結果の各行の一意の値であるということです。
なぜこのrowidが必要なのですか? OracleにはすでにRownumがあります。
SQLクエリでRowIDを使用した人はいますか?
解決
Rowidは行の物理的な位置です。したがって、それは、一次キーの検索よりも速く、行を見つける最も速い方法です。したがって、特定のタイプのトランザクションでは、いくつかの行を選択し、Rowidsを保存し、後でRowidsを使用する場合に役立ちます。 where
それらの同じ行に対するDMLの条項。
Oracle Select ... Updateのために、構文はRowIDを暗黙的に使用します。また、例外表(句に例外を伴う制約を適用するときに参照)には列row_idがあります。これにより、制約を破っている行をすばやく識別できます。
後者の例は、別の一般的な使用法を示しています。一般的なコードを書いている場合、データ型、複合キーなどに関する懸念なしにUIDを保存するメカニズムが必要です。
一方、rownumは、特定の結果セットで行をタグ付けする擬似柱です。永続的な意味はありません。
編集
特定のレコードのRowidは、たとえばテーブルの再構築を通じて、システムの寿命にわたって変化する可能性があります。また、1つのレコードが削除された場合、新しいレコードにそのRowidが与えられる可能性があります。したがって、Rowidsは長期的にはUIDとして使用するのに適していません。しかし、それらはトランザクション内で使用するのに十分です。
他のヒント
私は今、この例を知っています。
主要なキーのないテーブルがあるとします。したがって、このテーブルには行が複製できます。重複した行をどのように削除しますかが、その種の1つを正確に保持しますか?
Oracleは、Primary Keyの代替品としてRowidを提供します。相関タイプのネストされたクエリを書くことができます((行のすべての列によるグループ)内部クエリの各グループのmin(rowid)を取ることができます。
例
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は、特定のクエリの結果の行番号を提供します。 2つは非常に異なっており、交換可能ではありません。
また、Rownumのより近代的なバージョンであり、わずかに異なって動作するRow_Numberがあります。チェックアウト この記事 違いを説明しています。
Rowidは構成されています(ただし、必ずしもその順序ではありませんが、Rownum部分は私が覚えている限りRowidの最後の部分です):
- オブジェクトのユニークなdentifierをobjidします。
- テーブルスペースのデータファイルの相対数をファリノ。
- FileHeaderの後のデータファイルの相対ブロック番号をブロックします。
- ブロック内の相対的なrownum。
Rowidtochar()SQL-Functionを使用して、Rowidを複合フィールド(Objid、Fileno、Blockno、Rownum)に簡単に分解できます。
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
フィールドローウン(または上記のクエリの行)は いいえ SQL Pseudo Column Rowwhumと同じRownumは、SELECTクエリで使用しています。これは、結果セットで動的に生成された行のrownumberです。
この実装のため、行、ブロック、範囲、およびセグメントは、インデックスを無効にするRowIDを破ることなく輸送できないことに注意してください。
Rowidは、行が存在し、ユニークにinsefifelyのブロックへの最も直接的なアクセスパスです。これは、そのファイル内の一意のファイルとそのブロック内の一意の行をエンコードするためです。
詳しくは:
見る: dbms rowid形式に関するメモ
ノート:
Oracle Structures Database Files and Blocksの方法を少し理解し、いくつかのCプログラミングを知っている場合、Rowid(8K、またはどのブロックサイズが使用されているブロックの内容を表示するプログラムを簡単に作成できます。データベース、FileHeaderSize + blockno * block_sizeで始まるブロック。ブロックにはブロックヘッダーが含まれており、その後(テーブルがクラスター化されていないと仮定します)。 Rowdir内の位置0には、ブロック内の0行目の相対オフセット、Rowdir内の位置1で1秒の列の相対位置などがあります。行数自体はブロックヘッダーのどこかに保存されます(ブロックレイアウトのOraleドキュメントを参照)。
プログラミングの知識が少しあり、Oracleデータベースのドキュメントを検索して、ブロックの正確なレイアウトのブロックをファイルしているため、列がディスクに保存する方法を確認し、各列の行のすべての値を再構築することもできます。各行には、行の長さと列の数のメタデータが含まれており、各列の列のタイプとバイトサイズとその値の指標が含まれています。 bytesize 0は、列データが空(または:null)であることを意味します。
RowIDでは、基本的に、まったく同じデータを持つ2つの行を持つことができます。通常、主要なキーがRowidよりも少し意味のあるものであることを望んでいますが、それは行間の独自性を自動的に確保する単純な方法です。