チュートリアル: Apache Iceberg™ テーブルを作成する

概要

このチュートリアルでは、Snowflakeをカタログとして使用し、読み取りと書き込み操作をサポートする Apache Iceberg™ テーブル を作成する方法を説明します。SnowflakeのIcebergテーブルは、通常のSnowflakeテーブルのパフォーマンスとクエリセマンティクスを、管理する外部クラウドストレージと組み合わせます。

Snowsight のワークシートを使用するか、 SnowSQL などのSnowflakeクライアントを使用して、このチュートリアルを完了します。コード例をコピー&ペーストして実行することができます。

学習内容

このチュートリアルでは、次を実行する方法を学びます。

  • Snowflakeが管理するIcebergテーブル用に 外部ボリューム を作成および構成します。デモの目的で、チュートリアルではAmazon S3用の外部ボリュームを作成します。

  • SnowflakeをIcebergカタログとして使用する2つのIcebergテーブルを作成する(Snowflake管理テーブル)。

  • Icebergテーブルにデータを挿入します。

  • Icebergテーブルをクエリします。

  • Icebergテーブルから行を削除します。

前提条件

始める前に、以下のことをよく理解しておく必要があります。

次が必要です。

  • 以下のアクションを実行する権限を持つロールを持つ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;
Copy

外部ボリュームを作成する

Snowflake用の Apache Iceberg™ テーブルを作成するには、外部ボリュームが必要です。外部ボリュームは、外部クラウドストレージのIDおよびアクセス管理(IAM)エンティティを格納する、アカウントレベルのSnowflakeオブジェクトです。

Snowflakeは外部ボリュームを使用してクラウドストレージにセキュアに接続し、テーブルデータとメタデータにアクセスします。

デモのため、このステップではAmazon S3用の外部ボリュームの作成方法を説明します。別のクラウドストレージサービス用に外部ボリュームを作成するには、以下のトピックをご参照ください。

S3ロケーションへのアクセスを許可するIAMポリシーを作成する

AWS 管理コンソールでSnowflakeのアクセス許可を設定するには、次の手順を実行します。

  1. AWS 管理コンソールにログインします。

  2. ホームダッシュボードから、 IAM を検索して選択します。

  3. 左側のナビゲーションペインから Account settings を選択します。

  4. Endpoints リストの Security Token Service (STS) で、ご使用のアカウントが存在するSnowflake リージョン を見つけます。 STS status がアクティブでない場合は、トグルを Active に動かします。

  5. 左側のナビゲーションペインから Policies を選択します。

  6. Create Policy を選択します。

    AWS管理コンソールでIAMポリシーを作成します。
  7. Policy editor には、 JSON を選択します。

  8. 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": [
                            "*"
                         ]
                   }
                }
             }
       ]
    }
    
    Copy
  9. Next を選択します。

  10. Policy name (例: snowflake_access)とオプションの Description を入力します。

  11. Create policy を選択します。

IAMロールを作成する

AWS IAMロールを作成して、データファイルを含むS3バケットに対する権限を付与します。

  1. IDおよびアクセス管理(IAM)ダッシュボードの左側のナビゲーションペインから、 Roles を選択します。

  2. Create role を選択します。

  3. 信頼できるエンティティタイプでは、 AWS account を選択します。

  4. An AWS account の下で、 This account を選択します。後のステップで、信頼関係を変更し、Snowflake にアクセスを許可します。

  5. Require external ID オプションを選択します。好きな 外部 ID を入力します。例: iceberg_table_external_id

    外部 ID は、Snowflakeなどのサードパーティに AWS リソース(S3バケットなど)へのアクセスを許可するために使用されます。

    外部IDでIAMロールを作成します。
  6. Next を選択します。

  7. 外部ボリューム用に作成したポリシーを選択し、 Next を選択します。

  8. ロールの Role name と説明を入力し、 Create role を選択します。

    これで、S3ロケーションのIAMポリシー、およびIAMロールを作成し、ロールにポリシーを添付しました。

  9. View role を選択すると、ロールの概要ページが表示されます。ロールの ARN (Amazonリソース名)値を探して記録します。

    新しいIAMのロールを表示するリンク付きバナー。

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'
         )
      );
Copy

この例では、外部ボリューム用に作成したIAMロールに関連付けられた外部ID(iceberg_table_external_id)を指定しています。外部IDを指定すると、複数の外部ボリュームで同じIAMロール(および外部ID)を使用できます。

注釈

ARNsは、AWSが提供するのと同じように指定します。ARNsでは大文字と小文字が区別されます。

SnowflakeアカウントのAWS IAMユーザーを取得する

  1. DESCRIBE EXTERNAL VOLUME コマンドを使用して、Snowflakeアカウント用に自動的に作成された AWS IAM ユーザーの ARN を取得します。外部ボリュームの名前を指定します。

    次の例は、 iceberg_external_volume という名前の外部ボリュームを説明します。

    DESC EXTERNAL VOLUME iceberg_external_volume;
    
    Copy
  2. 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バケットのオブジェクトにアクセスできるように権限を設定します。

  1. AWS 管理コンソールにログインします。

  2. ホームダッシュボードから、 IAM を検索して選択します。

  3. 左側のナビゲーションペインから Roles を選択します。

  4. 外部ボリューム用に作成したIAMロールを選択します。

  5. Trust relationships タブを選択します。

  6. Edit trust policy を選択します。

  7. ポリシードキュメントをDESC EXTERNAL VOLUMEに記録した出力値で変更します。

    IAMロールの信頼ポリシーを更新します。

    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>"
            }
          }
        }
      ]
    }
    
    Copy

    条件:

    • snowflake_user_arn は、記録した STORAGE_AWS_IAM_USER_ARN 値です。

    • iceberg_table_external_id は外部 ID です。ロールの作成時に すでに 外部IDを指定し、同じIDを使用して外部ボリュームを作成した場合は、値をそのままにしてください。そうでない場合は、記録した値で sts:ExternalId を更新します。

    注釈

    新しい外部ボリュームを作成する場合(またはCREATE OR REPLACE EXTERNAL VOLUME構文を使用して既存の外部ボリュームを再作成する場合)に、独自の外部IDを提供しない場合は、このポリシードキュメントを更新する必要があります。セキュリティ上の理由から、新規または再作成された外部ボリュームは異なる外部 ID を持ち、この信頼ポリシーを更新しない限り、信頼関係を解決できません。

  8. 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';
Copy

チュートリアルの後半では、 SNOWFLAKE_SAMPLE_DATA データベースの snowflake_sample_data.tpch_sf1.customer テーブルからこのテーブルにデータを読み込みます。CREATEICEBERGTABLEステートメントの列定義は、サンプルテーブルと一致しています。

注釈

クラウドストレージの場所を確認すると、 BASE_LOCATION の下に、テーブル作成時にSnowflakeが書き込んだ metadata/ というディレクトリが表示されているはずです。このディレクトリには、テーブルのメタデータファイルが格納されます。

データベースのカタログ統合と外部ボリュームを設定する

次に、このチュートリアルで作成した iceberg_tutorial_dbCATALOGEXTERNAL_VOLUME パラメーターを設定します。パラメータを設定すると、変更後に作成される すべて のIcebergテーブルに、選択した特定のカタログと外部ボリュームを使用するようにSnowflakeに指示します。

ALTER DATABASE iceberg_tutorial_db SET CATALOG = 'SNOWFLAKE';
ALTER DATABASE iceberg_tutorial_db SET EXTERNAL_VOLUME = 'iceberg_external_volume';
Copy

確認するには、現在のデータベース(iceberg_tutorial_db)のパラメータをチェックしてください:

SHOW PARAMETERS IN DATABASE ;
Copy

CTASを使用してテーブルを作成する

最後に、CREATE ICEBERG TABLE ... AS SELECT 構文を使用して、 nation_iceberg という2つ目のIcebergテーブルを作成します。新しいテーブルは、Snowflakeサンプルデータベースの snowflake_sample_data.tpch_sf1.nation テーブルに基づきます。

注釈

iceberg_tutorial_db データベースに CATALOGEXTERNAL_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;
Copy

データをロードしてテーブルをクエリする

このステップでは、 INSERT INTO <table> を使用して、Snowflakeサンプルデータベースから customer_iceberg テーブルにデータをロードすることから始めます。

INSERT INTO customer_iceberg
  SELECT * FROM snowflake_sample_data.tpch_sf1.customer;
Copy

注釈

クラウドストレージの場所を確認すると、以下のパスにテーブルデータファイルが含まれるディレクトリがあるはずです: 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;
Copy

出力:

+--------------------+----------------+----------------+
| 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;
Copy

出力:

+--------------------+----------------+
| 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';
Copy

出力:

+------------------------+
| number of rows deleted |
|------------------------|
|                  29752 |
+------------------------+

最後に、行が消えたことを再確認できます。

SELECT
    c_name AS customer_name,
    c_mktsegment AS market_segment
 FROM customer_iceberg
 WHERE c_mktsegment = 'AUTOMOBILE';
Copy

出力:

+---------------+----------------+
| 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;
Copy

まとめおよび追加リソース

このチュートリアルでは、Snowflakeで管理された Apache Iceberg™ テーブルを作成して使用するためのエンドツーエンドのワークフローを説明しました。

その過程で、あなたは以下のタスクを完了しました:

Snowflake用Icebergテーブルの詳細については、 Icebergテーブルのドキュメント をご参照ください。その他のIcebergチュートリアルとクイックスタートについては、 Snowflakeチュートリアル ページをご参照ください。