Iceberg DML 操作
このドキュメントでは、StarRocksにおけるIcebergカタログのデータ操作言語(DML)操作について説明します。これには、Icebergテーブルへのデータ挿入が含まれます。
DML操作を実行するには、適切な権限が必要です。権限の詳細については、権限を参照してください。
INSERT
Icebergテーブルにデータを挿入します。この機能はv3.1以降でサポートされています。
StarRocksの内部テーブルと同様に、Icebergテーブルに対して INSERT 権限を持っている場合、 INSERT ステートメントを使用して、StarRocksテーブルのデータをそのIcebergテーブルにシンクできます(現在、Parquet形式のIcebergテーブルのみがサポートされています)。
構文
INSERT {INTO | OVERWRITE} <table_name>
[ (column_name [, ...]) ]
{ VALUES ( { expression | DEFAULT } [, ...] ) [, ...] | query }
-- 指定されたパーティションにデータをシンクする場合、次の構文を使用します。
INSERT {INTO | OVERWRITE} <table_name>
PARTITION (par_col1=<value> [, par_col2=<value>...])
{ VALUES ( { expression | DEFAULT } [, ...] ) [, ...] | query }
パーティション列は NULL 値を許可しません。したがって、Icebergテーブルのパーティション列に空の値がロードされないようにする必要があります。
パラメーター
INTO
StarRocks テーブルのデータを Iceberg テーブルに追加します。
OVERWRITE
StarRocks テーブルのデータで Iceberg テーブルの既存のデータを上書きします。
column_name
データをロードしたい宛先列の名前。1 つ以上の列を指定できます。複数の列を指定する場合、カンマ (,) で区切ります。Iceberg テーブルに実際に存在する列のみを指定できます。また、指定した宛先列には Iceberg テーブルのパーティション列を含める必要があります。指定した宛先列は、StarRocks テーブルの列と順番に 1 対 1 でマッピングされます。宛先列名が何であっても関係ありません。宛先列が指定されていない場合、データは Iceberg テーブルのすべての列にロードされます。StarRocks テーブルの非パーティション列が Iceberg テーブルの任意の列にマッピングできない場合、StarRocks は Iceberg テーブル列にデフォルト値 NULL を書き込みます。INSERT ステートメントに含まれるクエリステートメントの戻り列タイプが宛先列のデータタイプと異なる場合、StarRocks は不一致の列に対して暗黙の変換を行います。変換が失敗した場合、構文解析エラーが返されます。
expression
宛先列に値を割り当てる式。
DEFAULT
宛先列にデフォルト値を割り当てます。
query
Iceberg テーブルにロードされるクエリストートメントの結果。StarRocks がサポートする任意の SQL ステートメントである可能性があります。
PARTITION
データをロードしたいパーティション。Iceberg テーブルのすべてのパーティション列をこのプロパティで指定する必要があります。このプロパティで指定するパーティション列は、テーブル作成ステートメントで定義したパーティション列と異なる順序であってもかまいません。このプロパティを指定する場合、column_name プロパティを指定することはできません。
例
-
partition_tbl_1テーブルに 3 行のデータを挿入します。INSERT INTO partition_tbl_1VALUES("buy", 1, "2023-09-01"),("sell", 2, "2023-09-02"),("buy", 3, "2023-09-03"); -
簡単な計算を含む SELECT クエリの結果を
partition_tbl_1テーブルに挿入します。INSERT INTO partition_tbl_1 (id, action, dt) SELECT 1+1, 'buy', '2023-09-03'; -
partition_tbl_1テーブルからデータを読み取る SELECT クエリの結果を同じテーブルに挿入します。INSERT INTO partition_tbl_1 SELECT 'buy', 1, date_add(dt, INTERVAL 2 DAY)FROM partition_tbl_1WHERE id=1; -
partition_tbl_2テーブルのdt='2023-09-01'とid=1の 2 つの条件を満たすパーティションに SELECT クエリの結果を挿入します。INSERT INTO partition_tbl_2 SELECT 'order', 1, '2023-09-01';または
INSERT INTO partition_tbl_2 partition(dt='2023-09-01',id=1) SELECT 'order'; -
dt='2023-09-01'とid=1の 2 つの条件を満たすpartition_tbl_1テーブルのパーティション内のすべてのaction列の値をcloseで上書きします。INSERT OVERWRITE partition_tbl_1 SELECT 'close', 1, '2023-09-01';または
INSERT OVERWRITE partition_tbl_1 partition(dt='2023-09-01',id=1) SELECT 'close';
DELETE
指定された条件に基づいて Iceberg テーブルからデータを削除するには、DELETE ステートメントを使用できます。この機能は StarRocks v4.1 以降でサポートされています。
構文
DELETE FROM <table_name> WHERE <condition>
パラメーター
-
table_name: データを削除する Iceberg テーブルの名前。使用可能な形式:- 完全修飾名:
catalog_name.database_name.table_name - データベース修飾名(catalog 設定後):
database_name.table_name - テーブル名のみ(catalog とデータベースの設定後):
table_name
- 完全修飾名:
-
condition: 削除する行を識別する条件。以下を含めることができます:- 比較演算子:
=、!=、>、<、>=、<=、<> - 論理演算子:
AND、OR、NOT INおよびNOT IN句BETWEENおよびLIKE演算子IS NULLおよびIS NOT NULLINまたはEXISTSを含むサブクエリ
- 比較演算子:
例
基本的な DELETE 操作
単純な条件で行を削除する:
DELETE FROM iceberg_catalog.db.table1 WHERE id = 3;
IN および NOT IN を使用した DELETE
IN 句を使用して複数の行を削除する:
DELETE FROM iceberg_catalog.db.table1 WHERE id IN (18, 20, 22);
DELETE FROM iceberg_catalog.db.table1 WHERE id NOT IN (100, 101, 102);
論理演算子を使用した DELETE
複数の条件を組み合わせる:
DELETE FROM iceberg_catalog.db.table1 WHERE age > 30 AND salary < 70000;
DELETE FROM iceberg_catalog.db.table1 WHERE status = 'inactive' OR last_login < '2023-01-01';
パターン一致を使用した DELETE
LIKE を使用したパターンベースの削除:
DELETE FROM iceberg_catalog.db.table1 WHERE name LIKE 'A%';
DELETE FROM iceberg_catalog.db.table1 WHERE email LIKE '%@example.com';
範囲条件を使用した DELETE
BETWEEN を使用した範囲ベースの削除:
DELETE FROM iceberg_catalog.db.table1 WHERE age BETWEEN 30 AND 40;
DELETE FROM iceberg_catalog.db.table1 WHERE created_date BETWEEN '2023-01-01' AND '2023-12-31';
NULL チェックを使用した DELETE
NULL 値を含む行または NULL 値を含まない行を削除する:
DELETE FROM iceberg_catalog.db.table1 WHERE name IS NULL;
DELETE FROM iceberg_catalog.db.table1 WHERE email IS NULL AND phone IS NULL;
DELETE FROM iceberg_catalog.db.table1 WHERE age IS NOT NULL;
サブクエリを使用した DELETE
削除する行を識別するためにサブクエリを使用する:
-- IN サブクエリを使用した DELETE
DELETE FROM iceberg_catalog.db.table1 WHERE id IN (SELECT id FROM temp_table WHERE expired = true);
-- EXISTS サブクエリを使用した DELETE
DELETE FROM iceberg_catalog.db.table1 t1 WHERE EXISTS (SELECT user_id FROM inactive_users t2 WHERE t2.user_id = t1.user_id);
UPDATE
指定された条件に基づいて Iceberg テーブルの行を更新するには、UPDATE ステートメントを使用できます。この機能は v4.2 以降でサポートされています。
UPDATE は Iceberg V2 の Merge-On-Read モデルで実装しています。各 UPDATE は、古い行をマークする position delete ファイルと、更新後の行を含む新しいデータファイルを、単一の Iceberg スナップショットで原子的にコミットします。読み取り側は常に UPDATE 前または UPDATE 後の状態のみを観測し、中間状態を観測することはありません。書き込み結果は Spark などの他の Iceberg 対応エンジンとも相互運用可能です。
構文
UPDATE <table_name>
SET <column_name> = <expression> [, <column_name> = <expression> ...]
WHERE <condition>
パラメーター
-
table_name: 更新対象の Iceberg テーブル名。使用可能な形式:- 完全修飾名:
catalog_name.database_name.table_name - データベース修飾名(catalog 設定後):
database_name.table_name - テーブル名のみ(catalog とデータベース設定後):
table_name
- 完全修飾名:
-
column_name = expression: 更新対象列と新しい値。式は同一行の他の列、およびほかのサポートされている任意のスカラー関数を参照できます。 -
condition: 更新する行を識別する述語。サポートされる演算子はDELETEと同じです(比較演算子、論理演算子、IN/NOT IN、BETWEEN、LIKE、IS NULL/IS NOT NULL、IN/EXISTSサブクエリ)。
使用上の注意
- format-version 2 の Iceberg テーブルのみサポートされます。V1 と V3 テーブルへの UPDATE は解析時に拒否されます。
- フルテーブル更新を防ぐため、
WHERE句は 必須 です。 - パーティション列は更新できません。 パーティション割り当てを変更する必要がある場合は、
INSERT OVERWRITEを使用してください。 - 隠しメタデータ列
_fileおよび_posはSETで代入できません。 - Iceberg テーブルへの UPDATE では、
WITH(CTE)句およびFROM句は使用できません。 - Iceberg V2 には列のデフォルト値セマンティクスが存在しないため、
DEFAULT値はサポートされていません(initial-default / write-default は V3 の機能です)。 - 既存の Iceberg sink と同様に、Parquet 形式の Iceberg テーブルのみサポートされます。
- 並行 UPDATE は 直列化可能(serializable)分離 で実行されます。コミット時、StarRocks は読み取りスナップショットに対してデータファイルを再検証し、並行書き込みと衝突した場合、UPDATE はサイレントに上書きせずに失敗します。
例
基本的な UPDATE 操作
リテラル値で 1 つの列を更新する:
UPDATE iceberg_catalog.db.table1 SET status = 'inactive' WHERE id = 3;
複数列の更新
1 つのステートメントで複数の列を更新する:
UPDATE iceberg_catalog.db.table1
SET status = 'archived', archived_at = '2026-05-21'
WHERE last_login < '2024-01-01';
式を使用した UPDATE
新しい値は、行の既存列から計算できます:
UPDATE iceberg_catalog.db.table1
SET salary = salary * 1.05
WHERE department = 'engineering';
IN および論理演算子を使用した UPDATE
UPDATE iceberg_catalog.db.table1
SET status = 'flagged'
WHERE id IN (18, 20, 22);
UPDATE iceberg_catalog.db.table1
SET status = 'inactive'
WHERE age > 60 OR last_login IS NULL;
WHERE 句にサブクエリを含む UPDATE
UPDATE iceberg_catalog.db.orders
SET state = 'cancelled'
WHERE customer_id IN (SELECT id FROM inactive_customers);
NULL への設定
UPDATE iceberg_catalog.db.table1
SET email = NULL
WHERE email_verified = false;
モニタリング指標
Iceberg テーブルに対する各 UPDATE ステートメントは、以下の FE 側指標を更新します。これらは既存の iceberg_write_* および iceberg_delete_* と同じ iceberg_* 名前空間を共有し、標準の FE メトリクスエンドポイントから取得できます。
| 指標 | 単位 | ラベル | 説明 |
|---|---|---|---|
iceberg_update_total | 件数 | status(success、failed)、reason(none、timeout、oom、access_denied、unknown) | Iceberg テーブルを対象とする UPDATE タスク総数。各タスク終了時に 1 ずつ加算されます。 |
iceberg_update_duration_ms_total | ミリ秒 | — | Iceberg UPDATE タスクの累積実行時間。 |
iceberg_update_rows | 行 | — | Iceberg UPDATE が影響を与えた行の総数(生成されるファイル数に関係なく、1 行は 1 回のみカウントされます)。 |
iceberg_update_bytes | バイト | file_type(data、position_delete) | Iceberg UPDATE が書き込んだ総バイト数。新規データファイルと position delete ファイルを別々に集計します。 |
iceberg_update_files | 件数 | file_type(data、position_delete) | Iceberg UPDATE が書き込んだファイル総数。新規データファイルと position delete ファイルを別々に集計します。 |
MERGE INTO
MERGE INTO ステートメントを使用すると、ソースリレーションの各行がターゲットテーブルと一致するかどうかに基づいて、Iceberg テーブルの行の更新・削除・挿入を単一の原子的なステートメントで条件付きに実行できます。この機能は v4.2 以降でサポートされています。
MERGE INTO は UPDATE と同じ Iceberg V2 の Merge-On-Read コミットパスを再利用します。更新または削除された一致行は position delete ファイルを生成し、更新された行と新しく挿入された行は新しいデータファイルを生成し、それらすべてが単一の Iceberg スナップショットで一緒にコミットされます。読み取り側は常に MERGE 前または MERGE 後の状態のみを観測し、中間状態を観測することはありません。書き込み結果は Spark などの他の Iceberg 対応エンジンとも相互運用可能です。
構文
MERGE INTO <target_table> [ [AS] <target_alias> ]
USING <source_relation> [ [AS] <source_alias> ]
ON <merge_condition>
[ WHEN MATCHED [ AND <condition> ] THEN { UPDATE SET <column_name> = <expression> [, ...] | DELETE } ]
[ ... ]
[ WHEN NOT MATCHED [ AND <condition> ] THEN { INSERT (<column_name> [, ...]) VALUES (<expression> [, ...]) | INSERT * } ]
[ ... ]
パラメーター
-
target_table: 変更対象の Iceberg テーブル。使用可能な形式:- 完全修飾名:
catalog_name.database_name.table_name - データベース修飾名(catalog 設定後):
database_name.table_name - テーブル名のみ(catalog とデータベース設定後):
table_name
- 完全修飾名:
-
source_relation: merge を駆動するデータソース。テーブル、ビュー、または括弧で囲まれたサブクエリを指定できます。ON条件またはWHEN句がその列を参照する場合は、エイリアスを付けてください。 -
merge_condition: ターゲット行とソース行が一致するかどうかを判定するON述語。通常はキー列でターゲットとソースを結合します。 -
WHEN MATCHED [AND <condition>] THEN ...: ソース行に一致するターゲット行に適用されます。アクションはUPDATE SET(列挙した列を書き換える)またはDELETE(一致行を削除する)のいずれかです。複数のWHEN MATCHED句を記述でき、それぞれに任意のAND <condition>を付けられます。ある行に対しては、条件が成立する最初の句が適用されます。 -
WHEN NOT MATCHED [AND <condition>] THEN ...: どのターゲット行にも一致しないソース行に適用されます。アクションは新しい行の挿入で、明示的な列と値のリスト(INSERT (...) VALUES (...))、またはINSERT *(同名のソース列から各ターゲット列にマッピングする)を使用します。
使用上の注意
- format-version 2 の Iceberg テーブルのみサポートされます。V1、V3 テーブル、または非 Iceberg テーブル(ネイティブ OLAP テーブルなど)への MERGE INTO は解析時に拒否されます。
- 少なくとも 1 つの
WHEN句が必要です。 - 各ターゲット行は 最大 1 つ のソース行にのみ一致できます。あるターゲット行が複数のソース行に一致した場合、あいまいな変更を適用する代わりに、ステートメントは実行時に失敗します。必要に応じて、事前にソースを重複排除または集約してください。
WHEN MATCHED ... THEN UPDATE句ではパーティション列を更新できません。- 隠しメタデータ列
_fileおよび_posはUPDATE SETで代入できず、INSERTの対象にもできません。 - Iceberg V2 には列のデフォルト値セマンティクスが存在しないため、
DEFAULT値はサポートされていません。 INSERT (...) VALUES (...)では、値の数が列挙した列の数と一致する必要があり、同じ列を複数回列挙することはできません。- 無条件の
WHEN MATCHED句はWHEN MATCHED句の最後になければならず、無条件のWHEN NOT MATCHED句はWHEN NOT MATCHED句の最後になければなりません。 INSERT *は、ソースを名前で参照できることを要求します。明示的なエイリアス、または素のテーブル(この場合はテーブル名が使用されます)のいずれかです。ソースがサブクエリの場合は、明示的なエイリアスが必要です。- 既存の Iceberg sink と同様に、Parquet 形式の Iceberg テーブルのみサポートされます。
例
以下の例は、id、name、age、salary 列を持つ Iceberg テーブル iceberg_catalog.db.t_merge を対象とします。
Upsert(一致行を UPDATE、新しい行を INSERT)
最も一般的な MERGE パターンでは、既に存在する行を更新し、存在しない行を挿入します:
MERGE INTO iceberg_catalog.db.t_merge AS t
USING source_updates AS s
ON t.id = s.id
WHEN MATCHED THEN UPDATE SET name = s.name, age = s.age, salary = s.salary
WHEN NOT MATCHED THEN INSERT (id, name, age, salary) VALUES (s.id, s.name, s.age, s.salary);
一致行のみを UPDATE
MERGE INTO iceberg_catalog.db.t_merge AS t
USING (SELECT 3 AS id, 'UPDATED' AS name, 75000 AS salary) AS s
ON t.id = s.id
WHEN MATCHED THEN UPDATE SET name = s.name, salary = s.salary;
一致行を DELETE
MERGE INTO iceberg_catalog.db.t_merge AS t
USING (SELECT 2 AS id) AS s
ON t.id = s.id
WHEN MATCHED THEN DELETE;
一致しない行を INSERT
MERGE INTO iceberg_catalog.db.t_merge AS t
USING (SELECT 10 AS id, 'Frank' AS name, 40 AS age, 80000 AS salary) AS s
ON t.id = s.id
WHEN NOT MATCHED THEN INSERT (id, name, age, salary) VALUES (s.id, s.name, s.age, s.salary);
条件付き句
WHEN 句に AND <condition> を追加すると、行ごとにアクションを選択できます。一般的なユースケースは変更ストリーム(CDC)の適用です。ソース t_changes は各行を更新・削除・挿入のいずれかとしてマークする op 列を持ち、1 つの MERGE ステートメントでこの 3 種類すべてを振り分けます:
MERGE INTO iceberg_catalog.db.t_merge AS t
USING iceberg_catalog.db.t_changes AS s
ON t.id = s.id
WHEN MATCHED AND s.op = 'DELETE' THEN DELETE
WHEN MATCHED AND s.op = 'UPDATE' THEN UPDATE SET name = s.name, age = s.age, salary = s.salary
WHEN NOT MATCHED AND s.op <> 'DELETE' THEN INSERT (id, name, age, salary) VALUES (s.id, s.name, s.age, s.salary);
INSERT *
ソースがターゲットと同名の列を公開している場合、INSERT * は列を列挙せずにすべてのターゲット列を挿入します。ソースは名前で参照できる必要があり、サブクエリのソースにはエイリアスが必要です:
MERGE INTO iceberg_catalog.db.t_merge AS t
USING source_new_rows AS s
ON t.id = s.id
WHEN NOT MATCHED THEN INSERT *;
モニタリング指標
Iceberg テーブルに実際に書き込む MERGE INTO ステートメントは、コミット後に以下の FE 側指標を更新します。ファイルを生成しない no-op MERGE(たとえば空のソース、または一致・非一致のすべての行がフィルターされてどのアクションも適用されない場合)はコミットされずにスキップされ、これらのカウンターは増加しません。これらは既存の iceberg_write_*、iceberg_delete_*、iceberg_update_* と同じ iceberg_* 名前空間を共有し、標準の FE メトリクスエンドポイントから取得できます。
| 指標 | 単位 | ラベル | 説明 |
|---|---|---|---|
iceberg_merge_total | 件数 | status(success、failed)、reason(none、timeout、oom、access_denied、unknown) | Iceberg テーブルを対象とする MERGE INTO タスク総数。各タスク終了時に 1 ずつ加算されます。 |
iceberg_merge_duration_ms_total | ミリ秒 | — | Iceberg MERGE INTO タスクの累積実行時間。 |
iceberg_merge_rows | 行 | file_type(data、position_delete) | Iceberg MERGE INTO が処理した行の総数を、ファイル種別ごとに集計します。position_delete は UPDATE または DELETE によって命中したターゲット行(position delete として追加される)をカウントし、data は書き込まれたデータ行(更新された行と挿入された行)をカウントします。 |
iceberg_merge_bytes | バイト | file_type(data、position_delete) | Iceberg MERGE INTO が書き込んだ総バイト数。新規データファイルと position delete ファイルを別々に集計します。 |
iceberg_merge_files | 件数 | file_type(data、position_delete) | Iceberg MERGE INTO が書き込んだファイル総数。新規データファイルと position delete ファイルを別々に集計します。 |
TRUNCATE
Iceberg テーブルからすべてのデータを迅速に削除するには、TRUNCATE TABLE ステートメントを使用できます。
構文
TRUNCATE TABLE <table_name>
パラメーター
table_name: データを削除する Iceberg テーブルの名前。次の形式が使用できます:- 完全修飾名:
catalog_name.database_name.table_name - データベース修飾名(catalog 設定後):
database_name.table_name - テーブル名のみ(catalog とデータベースの設定後):
table_name
- 完全修飾名:
例
例 1: 完全修飾名を使用してテーブルを truncate
TRUNCATE TABLE iceberg_catalog.my_db.my_table;
例 2: catalog 設定後にテーブルを truncate
SET CATALOG iceberg_catalog;
TRUNCATE TABLE my_db.my_table;
例 3: catalog とデータベースの設定後にテーブルを truncate
SET CATALOG iceberg_catalog;
USE my_db;
TRUNCATE TABLE my_table;