チュートリアル: Apache Iceberg™ テーブルを作成する¶
概要¶
このチュートリアルでは、Snowflakeをカタログとして使用し、読み取りと書き込み操作をサポートする Apache Iceberg™ テーブル を作成する方法を説明します。SnowflakeのIcebergテーブルは、通常のSnowflakeテーブルのパフォーマンスとクエリセマンティクスを、管理する外部クラウドストレージと組み合わせます。
Snowsight のワークシートを使用するか、 SnowSQL などのSnowflakeクライアントを使用して、このチュートリアルを完了します。コード例をコピー&ペーストして実行することができます。
学習内容¶
このチュートリアルでは、次を実行する方法を学びます。
Snowflakeが管理するIcebergテーブル用に 外部ボリューム を作成および構成します。デモの目的で、チュートリアルではAmazon S3用の外部ボリュームを作成します。
SnowflakeをIcebergカタログとして使用する2つのIcebergテーブルを作成する(Snowflake管理テーブル)。
Icebergテーブルにデータを挿入します。
Icebergテーブルをクエリします。
Icebergテーブルから行を削除します。
前提条件¶
始める前に、以下のことをよく理解しておく必要があります。
Snowflake オブジェクト識別子 とその要件。
SnowflakeのApache IcebergとIcebergテーブル。詳細については、 Apache Iceberg™ テーブル をご参照ください。
クラウドオブジェクトストレージ。
S3を使用する場合、 AWS IDおよびアクセス管理(IAM) および IAM ポリシー要素 に精通している必要があります。
次が必要です。
以下のアクションを実行する権限を持つロールを持つSnowflakeユーザー:
30日間の試用アカウントを使用している場合は、アカウント用に作成されたユーザーとしてログインできます。このユーザーには、オブジェクトの作成に必要な権限を持ったロールがあります。
必要な権限を持つユーザーがいない場合は、権限のある人に作成を依頼します。ACCOUNTADMINロールを持つユーザーは、新しいユーザーを作成し、必要な権限を付与することができます。
外部ボリュームを設定するには、クラウドストレージプロバイダーの管理者アクセス権を取得します。
Snowflakeアカウントをホストしているのと同じクラウドプロバイダー(同じリージョン内)のストレージバケット(またはコンテナ)。
アカウント内のSNOWFLAKE_SAMPLE_DATAデータベースにアクセスできます。Snowflakeはデフォルトで新規アカウントにサンプルデータベースを作成します。アカウントにデータベースが作成されていない場合は、 サンプルデータベースの使用 をご参照ください。
ウェアハウスとデータベースを設定する¶
このチュートリアル用にウェアハウスとデータベースを作成し、環境を設定します。
CREATE WAREHOUSE iceberg_tutorial_wh
WAREHOUSE_TYPE = STANDARD
WAREHOUSE_SIZE = XSMALL;
USE WAREHOUSE iceberg_tutorial_wh;
CREATE OR REPLACE DATABASE iceberg_tutorial_db;
USE DATABASE iceberg_tutorial_db;
外部ボリュームを作成する¶
Snowflake用の Apache Iceberg™ テーブルを作成するには、外部ボリュームが必要です。外部ボリュームは、外部クラウドストレージのIDおよびアクセス管理(IAM)エンティティを格納する、アカウントレベルのSnowflakeオブジェクトです。
Snowflakeは外部ボリュームを使用してクラウドストレージにセキュアに接続し、テーブルデータとメタデータにアクセスします。
デモのため、このステップではAmazon S3用の外部ボリュームの作成方法を説明します。別のクラウドストレージサービス用に外部ボリュームを作成するには、以下のトピックをご参照ください。
S3ロケーションへのアクセスを許可するIAMポリシーを作成する¶
AWS 管理コンソールでSnowflakeのアクセス許可を設定するには、次の手順を実行します。
AWS 管理コンソールにログインします。
ホームダッシュボードから、 IAM を検索して選択します。
左側のナビゲーションペインから Account settings を選択します。
Endpoints リストの Security Token Service (STS) で、ご使用のアカウントが存在するSnowflake リージョン を見つけます。 STS status がアクティブでない場合は、トグルを Active に動かします。
左側のナビゲーションペインから Policies を選択します。
Create Policy を選択します。
Policy editor には、 JSON を選択します。
S3ロケーションへのデータの読み取りと書き込みに必要なアクセス許可をSnowflakeに提供するポリシーを追加します。
次のポリシー例は、指定したバケット内のすべての場所へのアクセスを許可します。
注釈
my_bucket
を実際のバケット名に置き換えてください。バケット内のパスを指定することもできます。例:my_bucket/path
。"s3:prefix":
条件を["*"]
に設定すると、指定したバケット内のすべてのプレフィックスへのアクセスを許可し、["path/*"]
に設定すると、バケット内の指定したパスへのアクセスを許可します。政府リージョン のバケットについては、ARNs のバケットは
arn:aws-us-gov:s3:::
のプレフィックスを使います。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:GetObjectVersion", "s3:DeleteObject", "s3:DeleteObjectVersion" ], "Resource": "arn:aws:s3:::<my_bucket>/*" }, { "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:GetBucketLocation" ], "Resource": "arn:aws:s3:::<my_bucket>", "Condition": { "StringLike": { "s3:prefix": [ "*" ] } } } ] }
Next を選択します。
Policy name (例:
snowflake_access
)とオプションの Description を入力します。Create policy を選択します。
IAMロールを作成する¶
AWS IAMロールを作成して、データファイルを含むS3バケットに対する権限を付与します。
IDおよびアクセス管理(IAM)ダッシュボードの左側のナビゲーションペインから、 Roles を選択します。
Create role を選択します。
信頼できるエンティティタイプでは、 AWS account を選択します。
An AWS account の下で、 This account を選択します。後のステップで、信頼関係を変更し、Snowflake にアクセスを許可します。
Require external ID オプションを選択します。好きな 外部 ID を入力します。例:
iceberg_table_external_id
。外部 ID は、Snowflakeなどのサードパーティに AWS リソース(S3バケットなど)へのアクセスを許可するために使用されます。
Next を選択します。
外部ボリューム用に作成したポリシーを選択し、 Next を選択します。
ロールの Role name と説明を入力し、 Create role を選択します。
これで、S3ロケーションのIAMポリシー、およびIAMロールを作成し、ロールにポリシーを添付しました。
View role を選択すると、ロールの概要ページが表示されます。ロールの ARN (Amazonリソース名)値を探して記録します。
Snowflakeで外部ボリュームを作成する¶
CREATE EXTERNAL VOLUME コマンドを使用して外部ボリュームを作成します。次の例は、暗号を使って単一Amazon S3ストレージロケーションを定義する iceberg_external_volume
という名前の外部ボリュームを作成しています。
CREATE OR REPLACE EXTERNAL VOLUME iceberg_external_volume
STORAGE_LOCATIONS =
(
(
NAME = 'my-s3-us-west-2'
STORAGE_PROVIDER = 'S3'
STORAGE_BASE_URL = 's3://<my_bucket>/'
STORAGE_AWS_ROLE_ARN = '<arn:aws:iam::123456789012:role/myrole>'
STORAGE_AWS_EXTERNAL_ID = 'iceberg_table_external_id'
)
);
この例では、外部ボリューム用に作成したIAMロールに関連付けられた外部ID(iceberg_table_external_id
)を指定しています。外部IDを指定すると、複数の外部ボリュームで同じIAMロール(および外部ID)を使用できます。
注釈
ARNsは、AWSが提供するのと同じように指定します。ARNsでは大文字と小文字が区別されます。
SnowflakeアカウントのAWS IAMユーザーを取得する¶
DESCRIBE EXTERNAL VOLUME コマンドを使用して、Snowflakeアカウント用に自動的に作成された AWS IAM ユーザーの ARN を取得します。外部ボリュームの名前を指定します。
次の例は、
iceberg_external_volume
という名前の外部ボリュームを説明します。DESC EXTERNAL VOLUME iceberg_external_volume;
STORAGE_AWS_IAM_USER_ARN
プロパティの値を記録します。これは、Snowflakeアカウント用に作成された AWS IAM ユーザーです(例:arn:aws:iam::123456789001:user/abc1-b-self1234
)。Snowflakeは、Snowflakeアカウント全体用に単一の IAM ユーザーをプロビジョニングします。アカウント内のすべてのS3外部ボリュームは、その IAM ユーザーを使用します。
注釈
外部ボリュームの作成時に外部ID(
STORAGE_AWS_EXTERNAL_ID
)を指定しなかった場合、Snowflakeがお客様が使用するIDを生成します。生成された外部IDでIAMのロール信頼ポリシーを更新できるように値を記録してください。
バケットオブジェクトにアクセスするためにIAMユーザー権限を付与する¶
このステップでは、Snowflakeアカウントの IAM ユーザーがS3バケットのオブジェクトにアクセスできるように権限を設定します。
AWS 管理コンソールにログインします。
ホームダッシュボードから、 IAM を検索して選択します。
左側のナビゲーションペインから Roles を選択します。
外部ボリューム用に作成したIAMロールを選択します。
Trust relationships タブを選択します。
Edit trust policy を選択します。
ポリシードキュメントをDESC EXTERNAL VOLUMEに記録した出力値で変更します。
IAM ロールのポリシードキュメント
{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "AWS": "<snowflake_user_arn>" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals": { "sts:ExternalId": "<iceberg_table_external_id>" } } } ] }
条件:
snowflake_user_arn
は、記録した STORAGE_AWS_IAM_USER_ARN 値です。iceberg_table_external_id
は外部 ID です。ロールの作成時に すでに 外部IDを指定し、同じIDを使用して外部ボリュームを作成した場合は、値をそのままにしてください。そうでない場合は、記録した値でsts:ExternalId
を更新します。
注釈
新しい外部ボリュームを作成する場合(またはCREATE OR REPLACE EXTERNAL VOLUME構文を使用して既存の外部ボリュームを再作成する場合)に、独自の外部IDを提供しない場合は、このポリシードキュメントを更新する必要があります。セキュリティ上の理由から、新規または再作成された外部ボリュームは異なる外部 ID を持ち、この信頼ポリシーを更新しない限り、信頼関係を解決できません。
Update policy を選択して変更を保存します。
テーブルを作成する¶
このステップでは2つの Apache Iceberg™ テーブルを作成します。1つは標準の CREATE ICEBERG TABLE 構文で、もう1つは CREATE ICEBERG TABLE ... AS SELECT 変数です。どちらのテーブルも、前の手順で設定した外部ボリュームを使用します。
また、データベースレベルでIcebergカタログと外部ボリュームを設定する方法についても説明します。
標準構文を使用してテーブルを作成する¶
まず、標準的なCREATEICEBERGTABLE構文を使用してIcebergテーブルを作成します。
テーブルがIcebergカタログとしてSnowflakeを使用するように、 CATALOG = 'SNOWFLAKE'
を指定します。
テーブルデータとメタデータの書き込み場所をSnowflakeに指示するには、 BASE_LOCATION
パラメーターに値を指定します。この例では、テーブル名(customer_iceberg
)を BASE_LOCATION
に設定しています。この方法で、Snowflakeは外部ボリュームの場所にあるテーブルと同じ名前のディレクトリにデータとメタデータを書き込みます。
CREATE OR REPLACE ICEBERG TABLE customer_iceberg (
c_custkey INTEGER,
c_name STRING,
c_address STRING,
c_nationkey INTEGER,
c_phone STRING,
c_acctbal INTEGER,
c_mktsegment STRING,
c_comment STRING
)
CATALOG = 'SNOWFLAKE'
EXTERNAL_VOLUME = 'iceberg_external_volume'
BASE_LOCATION = 'customer_iceberg';
チュートリアルの後半では、 SNOWFLAKE_SAMPLE_DATA データベースの snowflake_sample_data.tpch_sf1.customer
テーブルからこのテーブルにデータを読み込みます。CREATEICEBERGTABLEステートメントの列定義は、サンプルテーブルと一致しています。
注釈
クラウドストレージの場所を確認すると、 BASE_LOCATION
の下に、テーブル作成時にSnowflakeが書き込んだ metadata/
というディレクトリが表示されているはずです。このディレクトリには、テーブルのメタデータファイルが格納されます。
データベースのカタログ統合と外部ボリュームを設定する¶
次に、このチュートリアルで作成した iceberg_tutorial_db
に CATALOG
と EXTERNAL_VOLUME
パラメーターを設定します。パラメータを設定すると、変更後に作成される すべて のIcebergテーブルに、選択した特定のカタログと外部ボリュームを使用するようにSnowflakeに指示します。
ALTER DATABASE iceberg_tutorial_db SET CATALOG = 'SNOWFLAKE';
ALTER DATABASE iceberg_tutorial_db SET EXTERNAL_VOLUME = 'iceberg_external_volume';
確認するには、現在のデータベース(iceberg_tutorial_db
)のパラメータをチェックしてください:
SHOW PARAMETERS IN DATABASE ;
CTASを使用してテーブルを作成する¶
最後に、CREATE ICEBERG TABLE ... AS SELECT 構文を使用して、 nation_iceberg
という2つ目のIcebergテーブルを作成します。新しいテーブルは、Snowflakeサンプルデータベースの snowflake_sample_data.tpch_sf1.nation
テーブルに基づきます。
注釈
iceberg_tutorial_db
データベースに CATALOG
と EXTERNAL_VOLUME
パラメーターを設定しただけなので、CREATE ICEBERG TABLE ステートメントから両方のパラメーターを省略できます。 nation_iceberg
テーブルはデータベースから値を継承します。
CREATE OR REPLACE ICEBERG TABLE nation_iceberg (
n_nationkey INTEGER,
n_name STRING
)
BASE_LOCATION = 'nation_iceberg'
AS SELECT
N_NATIONKEY,
N_NAME
FROM snowflake_sample_data.tpch_sf1.nation;
データをロードしてテーブルをクエリする¶
このステップでは、 INSERT INTO <table>
を使用して、Snowflakeサンプルデータベースから customer_iceberg
テーブルにデータをロードすることから始めます。
INSERT INTO customer_iceberg
SELECT * FROM snowflake_sample_data.tpch_sf1.customer;
注釈
クラウドストレージの場所を確認すると、以下のパスにテーブルデータファイルが含まれるディレクトリがあるはずです: STORAGE_BASE_URL/BASE_LOCATION/customer_iceberg/data/
。
これでテーブルにデータが入ったので、クエリを実行できます。以下のクエリでは、 customer_iceberg
テーブルと nation_iceberg
テーブル(すでにデータが入っています)を結合します。
SELECT
c.c_name AS customer_name,
c.c_mktsegment AS market_segment,
n.n_name AS nation
FROM customer_iceberg c
INNER JOIN nation_iceberg n
ON c.c_nationkey = n.n_nationkey
LIMIT 15;
出力:
+--------------------+----------------+----------------+
| CUSTOMER_NAME | MARKET_SEGMENT | NATION |
|--------------------+----------------+----------------|
| Customer#000015001 | HOUSEHOLD | MOROCCO |
| Customer#000015002 | BUILDING | VIETNAM |
| Customer#000015003 | BUILDING | INDONESIA |
| Customer#000015004 | FURNITURE | SAUDI ARABIA |
| Customer#000015005 | HOUSEHOLD | KENYA |
| Customer#000015006 | BUILDING | UNITED KINGDOM |
| Customer#000015007 | MACHINERY | FRANCE |
| Customer#000015008 | HOUSEHOLD | INDIA |
| Customer#000015009 | FURNITURE | EGYPT |
| Customer#000015010 | HOUSEHOLD | ETHIOPIA |
| Customer#000015011 | FURNITURE | UNITED KINGDOM |
| Customer#000015012 | BUILDING | FRANCE |
| Customer#000015013 | FURNITURE | SAUDI ARABIA |
| Customer#000015014 | HOUSEHOLD | KENYA |
| Customer#000015015 | MACHINERY | ROMANIA |
+--------------------+----------------+----------------+
行を削除する¶
このステップでは、 DELETE ステートメントを使用して、 customer_iceberg
テーブルから特定の行を削除します。
まずテーブルの最初の10行をクエリし、4行が AUTOMOBILE
市場セグメントに属していることを確認します。
SELECT
c_name AS customer_name,
c_mktsegment AS market_segment
FROM customer_iceberg
LIMIT 10;
出力:
+--------------------+----------------+
| CUSTOMER_NAME | MARKET_SEGMENT |
|--------------------+----------------|
| Customer#000000001 | BUILDING |
| Customer#000000002 | AUTOMOBILE |
| Customer#000000003 | AUTOMOBILE |
| Customer#000000004 | MACHINERY |
| Customer#000000005 | HOUSEHOLD |
| Customer#000000006 | AUTOMOBILE |
| Customer#000000007 | AUTOMOBILE |
| Customer#000000008 | BUILDING |
| Customer#000000009 | FURNITURE |
| Customer#000000010 | HOUSEHOLD |
+--------------------+----------------+
次に、 DELETE ステートメントを使用して、市場セグメントが AUTOMOBILE
であるすべての行をテーブルから削除します。
DELETE FROM customer_iceberg WHERE c_mktsegment = 'AUTOMOBILE';
出力:
+------------------------+
| number of rows deleted |
|------------------------|
| 29752 |
+------------------------+
最後に、行が消えたことを再確認できます。
SELECT
c_name AS customer_name,
c_mktsegment AS market_segment
FROM customer_iceberg
WHERE c_mktsegment = 'AUTOMOBILE';
出力:
+---------------+----------------+
| CUSTOMER_NAME | MARKET_SEGMENT |
|---------------+----------------|
+---------------+----------------+
0 Row(s) produced. Time Elapsed: 1.426s
おめでとうございます。
Snowflakeで管理された最初のIcebergテーブルへの書き込みと読み込み、および変更が完了しました。また、Icebergテーブル ストレージ用に外部ボリュームを構成する方法や、データベース内のすべてのIcebergテーブルに対してIcebergカタログと外部ボリュームを設定する方法についても説明しました。
クリーンアップする¶
このチュートリアルで作成したオブジェクトをすべて削除するには、以下のDROPステートメントを実行します。
次の値を置換します。
my_other_database
を使用するデータベースの名前に置き換えて、このチュートリアル用に作成したものを削除できるようにします。作成した外部ボリュームの名前を持つ
my_other_warehouse
。
DROP ICEBERG TABLE customer_iceberg;
DROP ICEBERG TABLE nation_iceberg;
DROP EXTERNAL VOLUME iceberg_external_volume;
USE DATABASE <my_other_database>;
DROP DATABASE iceberg_tutorial_db;
USE WAREHOUSE <my_other_warehouse>;
DROP WAREHOUSE iceberg_tutorial_wh;
まとめおよび追加リソース¶
このチュートリアルでは、Snowflakeで管理された Apache Iceberg™ テーブルを作成して使用するためのエンドツーエンドのワークフローを説明しました。
その過程で、あなたは以下のタスクを完了しました:
Icebergテーブル用に外部ボリュームを構成しました。外部ボリュームとIcebergテーブルストレージの詳細については、 外部ボリュームの構成 をご参照ください。
Snowflakeサンプルデータベースのサンプルデータを使用して、 Snowflake管理Icebergテーブルを作成しました。関連情報については、以下のトピックをご参照ください。
テーブルへのデータ読み込み中については、 Snowflakeにデータをロードする をご参照ください。
データベースのIcebergカタログと外部ボリュームを設定します。これらのパラメータの設定については、以下のトピックをご参照ください。
Icebergテーブルへのデータのロード、クエリ、行の削除。Icebergテーブルとそのデータの管理については、 Apache Iceberg™ テーブルの管理 をご参照ください。
Snowflake用Icebergテーブルの詳細については、 Icebergテーブルのドキュメント をご参照ください。その他のIcebergチュートリアルとクイックスタートについては、 Snowflakeチュートリアル ページをご参照ください。