INSERT を使用したデータのロード
このトピックでは、SQL ステートメント - INSERT を使用して StarRocks にデータをロードする方法について説明します。
MySQL や他の多くのデータベース管理システムと同様に、StarRocks は INSERT を使用して内部テーブルにデータをロードすることをサポートしています。VALUES 句を使用して 1 行または複数行を直接挿入し、関数やデモをテストできます。また、クエリの結果で定義されたデータを 外部テーブルから内部テーブルに挿入することもできます。StarRocks v3.1 以降、INSERT コマンドとテーブル関数 FILES() を使用して、クラウドストレージ上のファイルから直接データをロードできます。
StarRocks v2.4 では、INSERT OVERWRITE を使用してテーブルにデータを上書きすることもサポートしています。INSERT OVERWRITE ステートメントは、上書き機能を実装するために次の操作を統合します。
- 元のデータを格納 するパーティションに従って一時パーティションを作成します。
- データを一時パーティションに挿入します。
- 元のパーティションを一時パーティションと交換します。
注意
データを上書きする前に検証する必要がある場合は、INSERT OVERWRITE を使用する代わりに、上記の手順に従ってデータを上書きし、パーティションを交換する前に検証できます。
v3.4.0 以降、StarRocks はパーティション化されたテーブルに対する INSERT OVERWRITE の新しいセマンティクス - Dynamic Overwrite をサポートしています。詳細については、Dynamic Overwrite を参照してください。
注意事項
- 同期 INSERT トランザクションをキャンセルするには、MySQL クライアントから Ctrl と C キーを押す必要があります。
- SUBMIT TASK を使用して非同期 INSERT タスクを送信できます。
- 現在の StarRocks のバージョンでは、任意の行のデータがテーブルのスキーマに準拠していない場合、INSERT トランザクションはデフォルトで失敗します。たとえば、任意の行のフィールドの長さがテーブルのマッピングフィールドの長さ制限を超える場合、INSERT トランザクションは失敗します。セッション変数
enable_insert_strict
をfalse
に設定すると、テーブルと一致しない行をフィルタリングしてトランザクションを続行できます。 - StarRocks に小さなデータバッチをロードするために INSERT ステートメントを頻繁に実行すると、過剰なデータバージョンが生成されます。これはクエリパフォーマンスに深刻な影響を与えます。運用環境では、INSERT コマンドを使用してデータを頻繁にロードしたり、日常的なデータロードのルーチンとして使用したりしないことをお勧めします。アプリケーションや分析シナリオがストリーミングデータや小さなデータバッチを個別にロードするソリューションを必要とする場合は、Apache Kafka® をデータソースとして使用し、Routine Load を介してデータをロードすることをお勧めします。
- INSERT OVERWRITE ステートメントを実行すると、StarRocks は元のデータを格納するパーティションに対して一時パーティションを作成し、新しいデータを一時パーティションに挿入し、元のパーティションを一時パーティションと交換します。これらの操作はすべて FE Leader ノードで実行されます。したがって、FE Leader ノードが INSERT OVERWRITE コマンドの実行中にクラッシュすると、ロードトランザクション全体が失敗し、一時パーティションが切り捨てられます。
準備
権限の確認
StarRocks のテーブルにデータを ロード するには、その StarRocks テーブルに対して INSERT 権限を持つユーザーである必要があります。INSERT 権限がない場合は、GRANT に記載されている手順に従って、StarRocks クラスターに接続するために使用するユーザーに INSERT 権限を付与してください。構文は GRANT INSERT ON TABLE <table_name> IN DATABASE <database_name> TO { ROLE <role_name> | USER <user_identity>}
です。
オブジェクトの作成
load_test
という名前のデータベースを作成し、宛先テーブルとして insert_wiki_edit
テーブルを、ソーステーブルとして source_wiki_edit
テーブルを作成します。
注意
このトピックで示されている例は、
insert_wiki_edit
テーブルとsource_wiki_edit
テーブルに基づいています。独自のテーブルとデータを使用することを希望する場合は、準備をスキップして次のステップに進むことができます。
CREATE DATABASE IF NOT EXISTS load_test;
USE load_test;
CREATE TABLE insert_wiki_edit
(
event_time DATETIME,
channel VARCHAR(32) DEFAULT '',
user VARCHAR(128) DEFAULT '',
is_anonymous TINYINT DEFAULT '0',
is_minor TINYINT DEFAULT '0',
is_new TINYINT DEFAULT '0',
is_robot TINYINT DEFAULT '0',
is_unpatrolled TINYINT DEFAULT '0',
delta INT DEFAULT '0',
added INT DEFAULT '0',
deleted INT DEFAULT '0'
)
DUPLICATE KEY(
event_time,
channel,
user,
is_anonymous,
is_minor,
is_new,
is_robot,
is_unpatrolled
)
PARTITION BY RANGE(event_time)(
PARTITION p06 VALUES LESS THAN ('2015-09-12 06:00:00'),
PARTITION p12 VALUES LESS THAN ('2015-09-12 12:00:00'),
PARTITION p18 VALUES LESS THAN ('2015-09-12 18:00:00'),
PARTITION p24 VALUES LESS THAN ('2015-09-13 00:00:00')
)
DISTRIBUTED BY HASH(user);
CREATE TABLE source_wiki_edit
(
event_time DATETIME,
channel VARCHAR(32) DEFAULT '',
user VARCHAR(128) DEFAULT '',
is_anonymous TINYINT DEFAULT '0',
is_minor TINYINT DEFAULT '0',
is_new TINYINT DEFAULT '0',
is_robot TINYINT DEFAULT '0',
is_unpatrolled TINYINT DEFAULT '0',
delta INT DEFAULT '0',
added INT DEFAULT '0',
deleted INT DEFAULT '0'
)
DUPLICATE KEY(
event_time,
channel,user,
is_anonymous,
is_minor,
is_new,
is_robot,
is_unpatrolled
)
PARTITION BY RANGE(event_time)(
PARTITION p06 VALUES LESS THAN ('2015-09-12 06:00:00'),
PARTITION p12 VALUES LESS THAN ('2015-09-12 12:00:00'),
PARTITION p18 VALUES LESS THAN ('2015-09-12 18:00:00'),
PARTITION p24 VALUES LESS THAN ('2015-09-13 00:00:00')
)
DISTRIBUTED BY HASH(user);
注意
v2.5.7 以降、StarRocks はテーブルを作成する際やパーティションを追加する際に、バケット数 (BUCKETS) を自動的に設定できます。バケット数を手動で設定する必要はありません。詳細については、バケット数の設定を参照してください。
INSERT INTO VALUES を使用したデータの挿入
INSERT INTO VALUES コマンドを使用して、特定のテーブルに 1 行または複数行を追加できます。複数行はカンマ (,) で区切られます。詳細な手順とパラメータの参照については、SQL リファレンス - INSERTを参照してください。
注意
INSERT INTO VALUES を使用したデータの挿入は、小さなデータセットでデモを検証する必要がある場合にのみ適用されます。大規模なテストや運用環境には推奨されません。StarRocks に大量のデータをロードするには、ロードオプションを参照して、シナリオに適した他のオプションを確認してください。
次の例では、ラベル insert_load_wikipedia
を使用して、データソーステーブル source_wiki_edit
に 2 行を挿入します。ラベルは、データベース内の各データロードトランザクションの一意の識別ラベルです。
INSERT INTO source_wiki_edit
WITH LABEL insert_load_wikipedia
VALUES
("2015-09-12 00:00:00","#en.wikipedia","AustinFF",0,0,0,0,0,21,5,0),
("2015-09-12 00:00:00","#ca.wikipedia","helloSR",0,1,0,1,0,3,23,0);
INSERT INTO SELECT を使用したデータの挿入
INSERT INTO SELECT コマンドを使用して、データソーステーブルのクエリ結果をターゲットテーブルにロードできます。INSERT INTO SELECT コマンドは、データソーステーブルのデータに対して ETL 操作を行い、StarRocks の内部テーブルにデータをロードします。データソースは、1 つまたは複数の内部または外部テーブル、さらにはクラウドストレージ上のデータファイルである可能性があります。ターゲットテーブルは、StarRocks の内部テーブルである必要があります。詳細な手順とパラメータの参照については、SQL リファレンス - INSERTを参照してください。
内部または外部テーブルから内部テーブルへのデータの挿入
注意
外部テーブルからのデータの挿入は、内部テーブルからのデータの挿入と同じです。簡単のため、以下の例では内部テーブルからのデータの挿入方法のみを示します。
- 次の例では、ソーステーブルからターゲットテーブル
insert_wiki_edit
にデータを挿入します。
INSERT INTO insert_wiki_edit
WITH LABEL insert_load_wikipedia_1
SELECT * FROM source_wiki_edit;
- 次の例では、ソーステーブルからターゲットテーブル
insert_wiki_edit
のp06
およびp12
パーティションにデータを挿入します。パーティションが指定されていない場合、データはすべてのパーティションに挿入されます。指定されたパーティ ションにのみデータが挿入されます。
INSERT INTO insert_wiki_edit PARTITION(p06, p12)
WITH LABEL insert_load_wikipedia_2
SELECT * FROM source_wiki_edit;
ターゲットテーブルをクエリして、データが存在することを確認します。
MySQL > select * from insert_wiki_edit;
+---------------------+---------------+----------+--------------+----------+--------+----------+----------------+-------+-------+---------+
| event_time | channel | user | is_anonymous | is_minor | is_new | is_robot | is_unpatrolled | delta | added | deleted |
+---------------------+---------------+----------+--------------+----------+--------+----------+----------------+-------+-------+---------+
| 2015-09-12 00:00:00 | #en.wikipedia | AustinFF | 0 | 0 | 0 | 0 | 0 | 21 | 5 | 0 |
| 2015-09-12 00:00:00 | #ca.wikipedia | helloSR | 0 | 1 | 0 | 1 | 0 | 3 | 23 | 0 |
+---------------------+---------------+----------+--------------+----------+--------+----------+----------------+-------+-------+---------+
2 rows in set (0.00 sec)
p06
および p12
パーティションを切り捨てると、クエリでデータは返されません。
MySQL > TRUNCATE TABLE insert_wiki_edit PARTITION(p06, p12);
Query OK, 0 rows affected (0.01 sec)
MySQL > select * from insert_wiki_edit;
Empty set (0.00 sec)
- 次の例では、ソーステーブルからターゲットテーブル
insert_wiki_edit
にevent_time
およびchannel
列を挿入します。指定されていない列にはデフォルト値が使用されます。
INSERT INTO insert_wiki_edit
WITH LABEL insert_load_wikipedia_3
(
event_time,
channel
)
SELECT event_time, channel FROM source_wiki_edit;
v3.3.1 以降、主キーテーブルに対する INSERT INTO ステートメントで列リストを指定すると、部分更新が実行されます(以前のバージョンでは完全アップサート)。列リストが指定されていない場合、システムは完全アップサートを実行します。
FILES() を使用して外部ソースのファイルから直接データを挿入
v3.1 以降、StarRocks は INSERT コマンドと FILES() 関数を使用して、クラウドストレージ上のファイルから直接データをロードすることをサポートしています。これにより、外部カタログやファイル外部テーブルを最初に作成する必要がなくなります。さらに、FILES() はファイルのテーブルスキーマを自動的に推測できるため、データロードのプロセスが大幅に簡素化されます。
次の例では、AWS S3 バケット inserttest
内の Parquet ファイル parquet/insert_wiki_edit_append.parquet からテーブル insert_wiki_edit
にデータ行を挿入します。
INSERT INTO insert_wiki_edit
SELECT * FROM FILES(
"path" = "s3://inserttest/parquet/insert_wiki_edit_append.parquet",
"format" = "parquet",
"aws.s3.access_key" = "XXXXXXXXXX",
"aws.s3.secret_key" = "YYYYYYYYYY",
"aws.s3.region" = "us-west-2"
);
INSERT OVERWRITE VALUES を使用したデータの上書き
INSERT OVERWRITE VALUES コマンドを使用して、特定のテーブルを 1 行または複数行で上書きできます。複数行はカンマ (,) で区切られます。詳細な手順とパラメータの参照については、SQL リファレンス - INSERTを参照してください。
注意
INSERT OVERWRITE VALUES を使用したデータの上書きは、小さなデータセットでデモを検証する必要がある場合にのみ適用されます。大規模なテストや運用環境には推奨されません。StarRocks に大量のデータをロードするには、ロードオプションを参照して、シナリオに適した他のオプションを確認してください。
ソーステーブルとターゲットテーブルをクエリして、データが存在することを確認します。
MySQL > SELECT * FROM source_wiki_edit;
+---------------------+---------------+----------+--------------+----------+--------+----------+----------------+-------+-------+---------+
| event_time | channel | user | is_anonymous | is_minor | is_new | is_robot | is_unpatrolled | delta | added | deleted |
+---------------------+---------------+----------+--------------+----------+--------+----------+----------------+-------+-------+---------+
| 2015-09-12 00:00:00 | #ca.wikipedia | helloSR | 0 | 1 | 0 | 1 | 0 | 3 | 23 | 0 |
| 2015-09-12 00:00:00 | #en.wikipedia | AustinFF | 0 | 0 | 0 | 0 | 0 | 21 | 5 | 0 |
+---------------------+---------------+----------+--------------+----------+--------+----------+----------------+-------+-------+---------+
2 rows in set (0.02 sec)
MySQL > SELECT * FROM insert_wiki_edit;
+---------------------+---------------+----------+--------------+----------+--------+----------+----------------+-------+-------+---------+
| event_time | channel | user | is_anonymous | is_minor | is_new | is_robot | is_unpatrolled | delta | added | deleted |
+---------------------+---------------+----------+--------------+----------+--------+----------+----------------+-------+-------+---------+
| 2015-09-12 00:00:00 | #ca.wikipedia | helloSR | 0 | 1 | 0 | 1 | 0 | 3 | 23 | 0 |
| 2015-09-12 00:00:00 | #en.wikipedia | AustinFF | 0 | 0 | 0 | 0 | 0 | 21 | 5 | 0 |
+---------------------+---------------+----------+--------------+----------+--------+----------+----------------+-------+-------+---------+
2 rows in set (0.01 sec)
次の例では、ソーステーブル source_wiki_edit
を 2 つの新しい行で上書きします。
INSERT OVERWRITE source_wiki_edit
WITH LABEL insert_load_wikipedia_ow
VALUES
("2015-09-12 00:00:00","#cn.wikipedia","GELongstreet",0,0,0,0,0,36,36,0),
("2015-09-12 00:00:00","#fr.wikipedia","PereBot",0,1,0,1,0,17,17,0);