Apache Iceberg™ テーブルのデータ型

Snowflakeは Apache Iceberg™仕様 で定義されたデータ型のほとんどをサポートし、Icebergデータ型をテーブルファイルに書き込むため、Snowflakeをカタログとして使用する場合は、異なるコンピュートエンジン間でIcebergテーブルの相互運用性を維持することができます。

SnowflakeがサポートするIcebergデータ型の概要については、 サポートされているデータ型 をご参照ください。

近似一致型

テーブルが、Snowflakeが 完全一致 をサポートしていないIcebergデータ型を使用している場合、Snowflakeは 近似一致 のSnowflake型を使用します。この型マッピングは、変換されたテーブルと、Snowflakeをカタログとして使用するIcebergテーブルの列の値に影響します。

例えば、Iceberg型 int の列を持つテーブルを考えてみましょう。Snowflakeは、Snowflakeデータ型 NUMBER(10,0)を使用して列の値を処理します。

NUMBER(10,0)の範囲は(-9,999,999,999,+9,999,999,999)ですが、 int の範囲はさらに制限された(-2,147,483,648,+2,147,483,647)です。その列に3,000,000,000の値を挿入しようとすると、Snowflakeは範囲外のエラーメッセージを返します。

近似一致型の詳細については、 サポートされているデータ型 表の注釈をご参照ください。

サポートされているデータ型

このセクションの次のテーブルは、Icebergデータ型とSnowflakeデータ型の関係を示しています。以下の列を使用します。

Iceberg型:

Apache Iceberg仕様で定義されているデータ型。Snowflakeをカタログとして使用する場合、SnowflakeはテーブルデータファイルにIceberg型を書き込むため、異なるコンピュートエンジン間でテーブルの相互運用性を維持することができます。

Snowflake型:

テーブルデータを処理して返すために使用されるSnowflakeデータ型。例えば、スキーマがIceberg型 timestamp を指定した場合、Snowflakeはマイクロ秒精度でSnowflakeデータ型 TIMESTAMP_NTZ(6) を使用して値を処理して返します。

注意:

近似一致型 を使用する際の注意事項を含む、その他の使用上の注意事項。

数値型

カタログとしてのSnowflake

次の表は、IcebergカタログとしてSnowflakeを使用するテーブル(Snowflake管理テーブル)のIceberg数値データ型とSnowflake数値データ型のマッピングを示しています。 Snowflake管理Icebergテーブルを作成する際、 Icebergデータ型 を使用して数値列を定義できます。

Icebergデータ型

Snowflakeデータ型

注意

int (32ビット符号付き整数)

NUMBER(10,0)

最小値より小さい10桁の数値、または32ビット符号付き整数の最大値より大きい値を挿入すると、範囲外のエラーが発生します。

long (64ビット符号付き整数)

NUMBER(19,0)

最小値より小さい19桁の数値、または64ビット符号付き整数の最大値より大きい値を挿入すると、範囲外のエラーが発生します。

float (単精度32ビット IEEE 754 浮動小数点)。

FLOAT

Snowflake DOUBLE データ型と同義語です。Snowflakeはすべての浮動小数点数を倍精度64ビット浮動小数点数として扱いますが、Icebergの浮動小数点数は32ビット浮動小数点数としてテーブルデータファイルに書き込まれます。

64ビットから32ビットへのビット幅を狭めるデータ変換では精度が失われます。

floatdouble を主キーとして使用することはできません(Apache Iceberg仕様 に準拠)。

double (倍精度64ビット IEEE 754浮動小数点)。

FLOAT

Snowflake DOUBLE データ型と同義語です。Snowflakeはすべての浮動小数点数を倍精度64ビット浮動小数点数として扱います。

64ビットから32ビットへのビット幅を狭めるデータ変換では精度が失われます。

floatdouble を主キーとして使用することはできません(Apache Iceberg仕様 に準拠)。

decimal(P,S)

NUMBER(P,S)

int の代わりに decimal(10,0) を指定すると、Icebergで10進数型が作成されます。decimal(19,0) を指定した場合も同様です。

外部カタログ

外部Icebergカタログを使用するIcebergテーブルを作成する場合、Icebergの数値型は次の表に従ってSnowflakeの数値型にマッピングされます。

Icebergデータ型

Snowflakeデータ型

int (32ビット符号付き整数)

NUMBER(10,0)

long (64ビット符号付き整数)

NUMBER(19,0)

float (単精度32ビット IEEE 754 浮動小数点)。

FLOAT

double (倍精度64ビット IEEE 754浮動小数点)。

FLOAT

decimal(P,S)

NUMBER(P,S)

注釈

floatdouble を主キーとして使用することはできません(Apache Iceberg仕様 に準拠)。

その他のデータ型

注釈

数値以外のデータ型については、カタログとしてSnowflakeを使用する場合、テーブル DDL で、Snowflakeデータ型を指定します(例えば、 list 型の代わりに構造化 ARRAY を使用します)。Snowflakeは、外部Icebergツールとの相互運用性のために、各Snowflakeタイプをテーブルメタデータ内の対応するIcebergデータ型に自動的にマッピングします。

Icebergデータ型

Snowflakeデータ型

注意

boolean

BOOLEAN

date

DATE

time

TIME(6)

Apache Icebergテーブルの仕様に従ったマイクロ秒精度。

timestamp

TIMESTAMP_NTZ(6)

Apache Icebergテーブルの仕様に従ったマイクロ秒精度。

タイムスタンプには、Parquet物理タイプ int96 を使用することもできます。Snowflakeは timestamp をマイクロ秒に変換します(Apache Icebergテーブル仕様による)。

timestamptz

TIMESTAMP_LTZ(6)

Apache Icebergテーブルの仕様に従ったマイクロ秒精度。

タイムスタンプには、Parquet物理タイプ int96 を使用することもできます。Snowflakeは timestamp をマイクロ秒に変換します(Apache Icebergテーブル仕様による)。

string

VARCHAR(134217728)

デフォルトのサイズは128 MB で、明示的に指定できるサイズは134217728(128 MB)のみです。

uuid

UUID

struct

構造化 OBJECT

構造化型列は最大1000個のサブ列をサポートします。

list

構造化 ARRAY

構造化型列は最大1000個のサブ列をサポートします。

map

MAP

構造化型列は最大1000個のサブ列をサポートします。

Iceberg v3データ型

重要

Iceberg v3データ型を使用するには、Icebergテーブルが準拠するApache Iceberg™仕様のバージョンを:code:`3`として指定する必要があります。バージョンの指定方法について詳しくは、:ref:`tables-iceberg-configuring-default-version`を参照してください。

次の表は、Icebergテーブルで使用できる|iceberg-tm|v3データ型を示しています。

Icebergデータ型

Snowflakeデータ型

注意

geography

GEOGRAPHY

Snowflakeは、Apache Iceberg™テーブル</user-guide/tables-iceberg>`の:ref:`label-data_types_geography`をサポートしています。GEOGRAPHY列を持つ、Snowflake管理または外部管理のIcebergテーブルを作成できます。GEOGRAPHY列を持つIcebergテーブルを作成するには、:doc:/sql-reference/sql/create-iceberg-table`コマンドを使用します。

注意

Icebergは、地理データを保存するためにWKB形式を使用します。この形式は、SnowflakeのGEOGRAPHY値に含めることができるすべてのデータを表すことはできません。:code:`Feature`および:code:`FeatureCollection`型はWKB形式ではサポートされていません。これらの型を持つGEOGRAPHY値をIcebergテーブルに挿入する際、Snowflakeはフィーチャーを基とする地理オブジェクトに変換し、すべてのプロパティをドロップします。Icebergテーブルの自動変換は、:doc:`ST_ASWKB</sql-reference/functions/st_aswkb>`関数とまったく同じように動作します。

GEOGRAPHYオブジェクトの場合、SRIDは常に4326です。

geometry

GEOMETRY

Snowflakeは、Apache Iceberg™テーブル</user-guide/tables-iceberg>`の:ref:`label-data_types_geometry`をサポートしています。GEOMETRY列を持つ、Snowflake管理または外部管理のIcebergテーブルを作成できます。GEOMETRY列を持つIcebergテーブルを作成するには、:doc:/sql-reference/sql/create-iceberg-table`コマンドを使用します。

注釈

単一列のすべてのGEOMETRYオブジェクトには、同じSRIDが必要です。

timestamp_ns

TIMESTAMP_NTZ(9)

Apache Icebergテーブル仕様に基づくナノ秒精度。タイムゾーンのセマンティクスなし(ウォールクロック)。TIMESTAMP(9)は最初、Snowflakeパラメーター:ref:`label-timestamp_type_mapping`の値に応じて、TIMESTAMP_NTZ(9)またはTIMESTAMP_LTZ(9)のSnowflake型にマップされます。その後、適切なIcebergデータ型にマッピングされます。

timestamptz_ns

TIMESTAMP_LTZ(9)

Apache Icebergテーブル仕様に基づくナノ秒精度。UTCとして保存されます。

TIMESTAMP(9)は最初、Snowflakeパラメーター:ref:`label-timestamp_type_mapping`の値に応じて、TIMESTAMP_NTZ(9)またはTIMESTAMP_LTZ(9)のSnowflake型にマップされます。その後、適切なIcebergデータ型にマッピングされます。

variant

VARIANT

Snowflakeは当初、標準のSnowflakeテーブル用に:ref:`VARIANT <label-data_type_variant>`データ型を開発しました。

VARIANTは、JSON、Avro、Protobufなどの動的半構造化データに効率的なバイナリエンコーディングを提供します。これにより、他のネストされたデータ型を含むデータの操作が容易になります。詳細については、 半構造化データ型 および Introduction to loading semi-structured data をご参照ください。

シュレッディング

Snowflakeは、VARIANTデータ型に組み込みのシュレッディング(:ref:`サブ列指向化<label-semistructured_columnarization>`とも呼ばれる)を提供します。シュレッディングは、VARIANT型の列からフィールドを抽出して個別のフィールドに変換し、各フィールドを列指向形式(サブ列)で格納するプロセスであり、特別な表記法を使用して走査およびクエリできます。

Snowflakeは、シュレッディングされたサブ列のメタデータと統計を追跡し、より高速で効率的なクエリのためのプルーニングを可能にします。

半構造化データをVARIANT列に挿入すると、Snowflakeは可能な限り多くのデータをシュレッディングします。

詳細については、 半構造化データファイルとサブカラム化 をご参照ください。

Iceberg v3データ型に関する考慮事項

Iceberg v3データ型を使用する場合は、次の点を考慮してください。

ナノ秒のタイムスタンプ

  • :code:`nanosecond timestamps`データ型の使用上の注意:

    • /sql-reference/sql/create-iceberg-table`および:doc:/sql-reference/sql/alter-iceberg-table`ステートメントでTIMESTAMP_NTZ(9)、TIMESTAMP_LTZ(9)、TIMESTAMP(9)のいずれかを使用します。``9``のスケールでは、新しいIcebergナノ秒型を指定します。``6``のスケールでは、従来のマイクロ秒型を引き続き指定します。

    • スケールを省略した場合、セッションレベルのパラメーター:code:`ICEBERG_TIMESTAMP_DEFAULT_SCALE`によって精度が制御されます。互換性のためにデフォルトは``6``のままです。Icebergタイムスタンプ列をデフォルトでナノ秒に設定したい場合は、パラメーターを``9``に設定します。

    • すべての標準的なIcebergパーティション変換(ID、バケット、年、月、日、時間など)は、マイクロ秒バリアントとまったく同じように、新しいナノ秒型を受け入れます。

    • 互換性

      • 読み取り/書き込み - 読み取りおよび書き込み操作は、Snowflake管理および外部管理のIcebergテーブルの両方でサポートされます。

      • 外部ツール - コネクタの変更は必要ありません。ナノ秒値は、読み取りおよび書き込み操作において標準的なIcebergの:code:`timestamp_ns`および:code:`timestamptz_ns`値として使用されます。

VARIANT

  • Icebergテーブルで:code:`VARIANT`データ型を使用する場合は、以下の考慮事項と制限を考慮してください。

    • Icebergデータ型に関する通常の考慮事項は、VARIANTデータ型にも適用されます。詳しくは、:ref:`Icebergテーブルのデータ型を操作する際の考慮事項<label-tables_iceberg_data_types_considerations>`を参照してください。

    • VARIANT列のオブジェクトのキーは、STRING型である必要があります。

    • SnowpipeまたはCOPY INTOを使用して、バリアント列を持つIcebergテーブルにデータをロードすることがサポートされています。ただし、SnowpipeおよびCOPYINTOは、ネストされたバリアント列を含むOBJECT、ARRAY、MAP列へのデータロードには使用できません。

    • ネストされたバリアントはサポートされていません。

    • :doc:`/user-guide/semistructured-considerations`も参照してください。

次のセクションでは、Iceberg v3データ型の例を示します。

GEOGRAPHY

GEOGRAPHY列にデータを挿入するには、入力データを指定します。次の例では、Well-Known Text(WKT)として定義された地理空間オブジェクトを、前の例で作成した``geog_points``テーブルの``geog``列に挿入します。

INSERT INTO geog_points
  SELECT TO_GEOGRAPHY('POINT(-122.3861109 37.61637595)');
Copy

GEOGRAPHY値を明示的に作成せずに、地理空間データを挿入することもできます。

INSERT INTO geog_points
  SELECT 'POINT(-122.3861109 37.61637595)';
Copy
GEOMETRY

次の例では、``4326``のデフォルトSRIDを持つ、``geom``という名前の単一のGEOMETRY列を含む空のIcebergテーブルを作成します。

CREATE ICEBERG TABLE geo_points (geom GEOMETRY)
  CATALOG = 'SNOWFLAKE'
  EXTERNAL_VOLUME = 'my_external_volume'
  BASE_LOCATION = 'us_states'
  ICEBERG_VERSION = 3;
Copy

DDLステートメントでSRIDを明示的に設定することもできます。次の例では、SRIDを``4269``に設定します。

CREATE ICEBERG TABLE geo_points (geom GEOMETRY(4269))
  CATALOG = 'SNOWFLAKE'
  EXTERNAL_VOLUME = 'my_external_volume'
  BASE_LOCATION = 'us_states'
  ICEBERG_VERSION = 3;
Copy

GEOMETRY列にデータを挿入するには、入力データを指定します。次の例では、Well-Known Text(WKT)として定義された地理空間オブジェクトを、前の例で作成した``geo_points``テーブルの``geom``列に挿入します。

INSERT INTO geo_points
  SELECT TO_GEOMETRY('POINT(-122.3861109 37.61637595)');
Copy

GEOMETRY値を明示的に作成せずに、地理空間データを挿入することもできます。

INSERT INTO geo_points
  SELECT 'POINT(-122.3861109 37.61637595)';
Copy

SRIDがGEOMETRYオブジェクトの一部として使用できない場合は、コンストラクター関数を使用して明示的に設定できます。

INSERT INTO geo_points
  SELECT TO_GEOMETRY('POINT(-122.3861109 37.61637595)', 4326);
Copy
ナノ秒のタイムスタンプ

次の例では、ナノ秒のタイムスタンプを持つマネージドIcebergテーブルを作成します。

CREATE ICEBERG TABLE sensor_readings (
    reading_ntz TIMESTAMP_NTZ(9),
    reading_ltz TIMESTAMP_LTZ(9))
  ICEBERG_VERSION = 3;
Copy

このステートメントに対して、Snowflakeは次のデータ型マッピングを実行します。

  • ``reading_ntz``列のデータ型は、:code:`timestamp_ns`Iceberg v3データ型にマップされます。

  • ``reading_ltz``列のデータ型は、:code:`timestamptz_ns`Iceberg v3データ型にマップされます。

VARIANT

:doc:`/sql-reference/sql/create-iceberg-table`コマンドを使用して、VARIANT列を持つIcebergテーブルを作成できます。

次の例では、``record``という名前の単一のVARIANT列を含む空のSnowflake管理Icebergテーブルを作成します。

CREATE ICEBERG TABLE car_sales (record VARIANT)
  CATALOG = 'SNOWFLAKE'
  EXTERNAL_VOLUME = 'my_external_volume'
  BASE_LOCATION = 'car_sales'
  ICEBERG_VERSION = 3;
Copy

同様に、次の例では、カタログリンクのデータベースに空の外部管理Icebergテーブルを作成し、Snowflakeが書き込みを行えるようにします。

USE DATABASE my_catalog_linked_db;

USE SCHEMA my_namespace;

CREATE ICEBERG TABLE car_sales (record VARIANT)
ICEBERG_VERSION = 3;
Copy

VARIANT列にデータを挿入するには、入力データ形式を指定します。次の例では、:doc:`/sql-reference/functions/parse_json`関数を使用して、JSON形式のデータを``car_sales``テーブルの``record``列(先ほど作成済み)に挿入します。

INSERT INTO car_sales SELECT
  PARSE_JSON(
    '{
        "date" : "2017-04-28",
        "dealership" : "Valley View Auto Sales",
        "salesperson" : {
          "id": "55",
          "name": "John Salesperson"
        },
        "customer" : [
          {"name": "Alice Doe", "phone": "14151234567", "address": "San Francisco, CA"},
          {"name": "Bob Doe", "phone": "14151234567", "address": "San Francisco, CA"}
        ],
        "vehicle" : [
          {"make": "Honda", "model": "Civic", "year": "2017", "price": "20275", "extras":["ext warranty", "paint protection"]}
        ]
      }'
    );
Copy

テーブルでSELECT * FROMステートメントを実行すると、次の出力が返されます。

+--------------------------------------------+
| RECORD                                     |
|--------------------------------------------|
| {                                          |
|    "customer": [                           |
|      {                                     |
|        "address": "San Francisco, CA",     |
|        "name": "Alice Doe",                |
|        "phone": "14151234567"              |
|      },                                    |
|      {                                     |
|        "address": "San Francisco, CA",     |
|        "name": "Bob Doe",                  |
|        "phone": "14151234567"              |
|      }                                     |
|    ],                                      |
|    "date": "2017-04-28",                   |
|    "dealership": "Valley View Auto Sales", |
|    "salesperson": {                        |
|      "id": "55",                           |
|      "name": "John Salesperson"            |
|    },                                      |
|    "vehicle": [                            |
|      {                                     |
|        "extras": [                         |
|          "ext warranty",                   |
|          "paint protection"                |
|        ],                                  |
|        "make": "Honda",                    |
|        "model": "Civic",                   |
|        "price": "20275",                   |
|        "year": "2017"                      |
|      }                                     |
|    ]                                       |
|  }                                         |
+--------------------------------------------+

VARIANT列のデータをクエリするには、ドットまたはブラケット表記を使用して、データにネストされた要素にアクセスできます。

次の例では、ドット表記を使用して、車を販売したすべての営業担当者の名前を取得します。テーブルには1つの行があるため、クエリは単一の結果値を生成します。

SELECT record:salesperson.name
  FROM car_sales
  ORDER BY 1;
Copy

出力:

+-------------------------+
| RECORD:SALESPERSON.NAME |
|-------------------------|
| "John Salesperson"      |
+-------------------------+
Copy

半構造化データのクエリについて詳しくは、:doc:`/user-guide/querying-semistructured`を参照してください。

注釈

  • Apache Sparkを使用してバリアント列を持つIcebergテーブルを読み書きする場合は、バリアントをサポートしているApache Spark 4.0以降を使用する必要があります。

    Snowflake管理Icebergテーブルのバリアント列は、Apache SparkなどのIcebergバリアントをサポートするエンジンで読み取ることができます。エンジンは、:doc:`Horizon Iceberg RESTカタログAPI </user-guide/tables-iceberg-query-using-external-query-engine-snowflake-horizon>`を介してSnowflake管理Iceberg v3テーブルを読み取ることができます。

    spark.sql("""
    SELECT
    variant_get(record, '$.customer[0].name', 'string') AS customer_1_name
    variant_get(record, '$.salesperson.name', 'string') AS name
    FROM CAR_SALES
    ORDER BY name
    """).show()
    
    Copy

    同様に、Snowflakeは、バリアント列を含む外部管理Icebergテーブルの読み取りまたは書き込みを行うことができます。

  • Snowflakeは、必要に応じてnull値をテーブルに書き込むことができます。

    例:

    INSERT INTO my_table_new
      SELECT ARRAY_CONSTRUCT(
          OBJECT_CONSTRUCT_KEEP_NULL('field1', NULL, 'field2', 123)
      )::ARRAY(OBJECT(field1 STRING, field2 INT));
    
    Copy

デルタデータ型

次の表は、 デルタテーブルファイルから作成されたIcebergテーブル について、デルタデータ型とSnowflakeデータ型の対応関係を示しています。

デルタ型

Snowflakeデータ型

注意

BINARY

BINARY

BOOLEAN

BOOLEAN

BYTE

NUMBER(3,0)

DATE

DATE

DECIMAL(P,S)

NUMBER(P,S)

DOUBLE

REAL

FLOAT

REAL

INTEGER

NUMBER(10,0)

LONG

NUMBER(20,0)

SHORT

NUMBER(5,0)

STRING

TEXT

TIMESTAMP

TIMESTAMP_LTZ(6)

Parquet 物理タイプ int96 を TIMESTAMP に使用することもできますが、Snowflake では TIMESTAMP_NTZ に int96 をサポートしていません。

TIMESTAMP_NTZ

TIMESTAMP_NTZ(6)

次の表は、デルタ入れ子データ型がSnowflakeデータ型にどのようにマッピングされるかを示しています。

デルタ入れ子型

Snowflakeデータ型

STRUCT

構造化 OBJECT

ARRAY

構造化 ARRAY

MAP

MAP

考慮事項

Icebergテーブルのデータ型で作業する場合、次の項目を考慮してください。

  • 次のIcebergデータ型を使用する列を持つ テーブルの変換 はサポートされていません。

    • uuid

    • fixed(L)

  • Snowflakeをカタログとして使用するテーブルでは、Iceberg uuid データ型を使用するテーブルの作成はサポートされていません。

  • 外部カタログを使用するテーブルの場合、OBJECT、ARRAY、MAPのいずれかを含む構造化された型の列を持つIceberg v3テーブルを作成することができません。たとえば、CREATE ICEBERG TABLE … AS SELECT (CTAS)を使用して、構造化された型の列を持つ外部管理Iceberg v3テーブルを作成することができません。

    構造化された型の列を持つSnowflake管理Iceberg v3テーブルを作成できます。

  • すべてのIcebergテーブルタイプ用:

    • 構造化型列は最大1000個のサブ列をサポートします。

    • Icebergは時刻とタイムスタンプ型のマイクロ秒精度をサポートしています。その結果、ミリ秒やナノ秒などの別の精度を使用するIcebergテーブルをSnowflakeでは作成できません。

    • floatdouble を主キーとして使用することはできません(Apache Iceberg仕様 に準拠)。

    • LIST 論理的タイプを使用する Parquet ファイルでは、以下の点に注意してください。

      • element キーワードによる3レベルの注釈構造がサポートされています。詳細については、 Parquet理論型の定義 をご参照ください。Parquet ファイルが array キーワードで廃止された形式を使用している場合は、サポートされている形式に基づいてデータを再生成する必要があります。

  • Deltaファイルから作成されたテーブルについては、以下の点に注意してください。

    • 以下の機能やデータタイプを使用したParquetファイル(Delta テーブルのデータファイル)はサポートされていません。

      • フィールド IDs

      • INTERVAL データ型。

      • 38以上の精度を持つ DECIMAL データ型。

      • LIST または MAP で、1レベルまたは2レベルの表現を持つタイプ。

      • 符号なし整数型 (INT(signed = false))。

      • FLOAT16 データ型。

    • TIMESTAMP にParquet物理タイプ int96 を使用できますが、Snowflakeでは TIMESTAMP_NTZ に int96 をサポートしていません。