YashanDBでは、シングルインスタンスおよび共有クラスタ構成において、テーブルオブジェクトのデフォルト格納方式としてHEAP方式が採用されています。データは行単位で編成され、各行の物理的な格納位置からグローバルに一意な識別子、すなわちROWIDが生成されます。ROWIDはテーブルデータの検索におけるアドレス解決に利用されるほか、各行を一意に識別する手段としても機能します。
ROWIDは特殊なデータ型であり、カラムのデータ型としてユーザが明示的に宣言できる一方、疑似カラム(テーブル構造に定義されていないが、SELECT文で参照可能なカラム)としても利用できます。
UROWID(Universal ROWID)は、YashanDBにおけるデータ型の一つで、行テーブルのROWIDをバイナリ文字列として格納するために使用されます。
ストレージ属性
| 型 | バイト長 |
|---|---|
| ROWID | 16 |
| UROWID | 1~8000、デフォルトは4000 |
定義構文
| 型 | 構文 | ルール |
|---|---|---|
| ROWID | ROWID | 後述のデータ形式に従う |
| UROWID | UROWID(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