YashanDBにおけるROWIDとUROWIDのデータ型解説

YashanDBでは、シングルインスタンスおよび共有クラスタ構成において、テーブルオブジェクトのデフォルト格納方式としてHEAP方式が採用されています。データは行単位で編成され、各行の物理的な格納位置からグローバルに一意な識別子、すなわちROWIDが生成されます。ROWIDはテーブルデータの検索におけるアドレス解決に利用されるほか、各行を一意に識別する手段としても機能します。

ROWIDは特殊なデータ型であり、カラムのデータ型としてユーザが明示的に宣言できる一方、疑似カラム(テーブル構造に定義されていないが、SELECT文で参照可能なカラム)としても利用できます。

UROWID(Universal ROWID)は、YashanDBにおけるデータ型の一つで、行テーブルのROWIDをバイナリ文字列として格納するために使用されます。

ストレージ属性

バイト長
ROWID16
UROWID1~8000、デフォルトは4000

定義構文

構文ルール
ROWIDROWID後述のデータ形式に従う
UROWIDUROWID(Size)可変長バイナリ文字列。Sizeを省略した場合、デフォルト長は4000
  • Size: 最大バイト長を指定。

データ形式

ROWIDのデータ形式は dataoid:spaceid:fileid:blockid:dir です。

行テーブルのROWIDをUROWIDで格納する場合、そのデータ形式は 0x1 + ROWIDの16進数表現 となります。

# dataoid

データオブジェクトID。行が属するセグメントのIDで、USER_OBJECTSビューのDATA_OBJECT_IDフィールドなどから取得可能です。

# spaceid

スペースID。行が属するテーブルスペースのIDで、V$TABLESPACEビューのIDフィールドなどから取得可能です。

# fileid

ファイルID。行が存在するデータファイルの、該当テーブルスペース内でのIDです。V$DATAFILEビューのIDフィールドなどから取得可能です。

# blockid

ブロックID。行が格納されているデータブロックの、該当ファイル内でのブロックIDです。

# dir

ディレクトリ(スロット位置)。行がデータブロック内のどのスロットに位置するかを示します。

ROWIDの使用ルール

ROWIDは疑似カラムとして利用可能ですが、SELECT * では取得できず、明示的に指定する必要があります。

ROWIDはカラムのデータ型としても利用でき、ROWID型データの格納、およびINSERT、UPDATE、DELETE、SELECTといったDML操作をサポートします。

DML操作において、YashanDBはROWIDとUROWID、RAW、文字型の間での暗黙的なデータ型変換をサポートします。ただし、ROWIDを関数の引数として渡す場合、関数が期待する引数のデータ型と異なると、暗黙変換は行われずエラーが返されます。

ROWID型データの使用制限は以下の通りです。

  • パーティションキーとして使用不可
  • HEAPテーブルでのみ有効。分散HEAPテーブルではROWIDをサポートしません。

ROWID疑似カラムの使用制限は以下の通りです。

  • DISTINCT、GROUP BY、CONNECT BY、JOIN演算子、ROWNUM疑似カラム、または集計関数を含むサブクエリ内ではROWID疑似カラムを使用できません。

例(HEAPテーブル)

-- ROWID疑似カラムの確認
SELECT ROWID, * FROM area WHERE area_no = '01';
ROWID              AREA_NO AREA_NAME    DHQ     
--------------------------------------------------
1350:5:0:148:0     01      华东         Shanghai

-- ROWIDの長さを確認
SELECT LENGTH(ROWID) FROM area WHERE area_no = '01';
        LENGTH(ROWID)
---------------------
                  14

-- ISNULL関数でROWIDを使用した場合に型エラーが発生する例
SELECT ISNULL(ROWID) FROM area WHERE area_no = '01';
[1:7]YAS-04401 data type STRING expected, but ROWID got

-- ROWID疑似カラムをGROUP BYを含むサブクエリで使用した場合のエラー例
SELECT ROWID FROM (SELECT area_no FROM area GROUP BY area_no);
YAS-04827 cannot select ROWID from, or sample, a view with DISTINCT, GROUP BY, etc.

-- ROWID型のカラムを持つテーブルを作成し、挿入
CREATE TABLE rowid_base (id INT);
BEGIN
  FOR i IN 1..10 LOOP
    INSERT INTO rowid_base VALUES (i);
  END LOOP;
  COMMIT;
END;
/

CREATE TABLE rowid_test (c1 ROWID);
INSERT INTO rowid_test SELECT ROWID FROM rowid_base;

-- 文字列リテラルからROWID型へ直接挿入
INSERT INTO rowid_test VALUES ('1350:5:0:148:0');

UROWIDの使用ルール

YashanDB内部ではUROWIDはRAW型と同等に扱われるため、UROWIDの使用ルールはRAW型と完全に同一です。

例(HEAPテーブル)

-- UROWID型のテーブルを作成し、ROWIDから変換して挿入
CREATE TABLE urowid_table (c1 UROWID);
INSERT INTO urowid_table SELECT ROWID FROM rowid_test;

-- 16進数リテラルからUROWIDへ挿入
INSERT INTO urowid_table VALUES ('1234ABCD');

-- UROWID値をROWID型と比較しようとするとエラー
INSERT INTO rowid_test 
SELECT c1 FROM urowid_table
WHERE c1 = '1234ABCD';
YAS-00008 type convert error : invalid ROWID

-- ISNULL関数でUROWIDを使用可能
SELECT ISNULL(c1) FROM urowid_table
WHERE c1 = '0171070000000000000061000009000500' AND ROWNUM = 1;
ISNULL(C1)           
---------------------
false

タグ: YashanDB ROWID UROWID データ型 HEAPテーブル

6月16日 17:02 投稿