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データ型 |
注意 |
|---|---|---|
|
最小値より小さい10桁の数値、または32ビット符号付き整数の最大値より大きい値を挿入すると、範囲外のエラーが発生します。 |
|
|
最小値より小さい19桁の数値、または64ビット符号付き整数の最大値より大きい値を挿入すると、範囲外のエラーが発生します。 |
|
|
Snowflake DOUBLE データ型と同義語です。Snowflakeはすべての浮動小数点数を倍精度64ビット浮動小数点数として扱いますが、Icebergの浮動小数点数は32ビット浮動小数点数としてテーブルデータファイルに書き込まれます。 64ビットから32ビットへのビット幅を狭めるデータ変換では精度が失われます。
|
|
|
Snowflake DOUBLE データ型と同義語です。Snowflakeはすべての浮動小数点数を倍精度64ビット浮動小数点数として扱います。 64ビットから32ビットへのビット幅を狭めるデータ変換では精度が失われます。
|
|
|
|
外部カタログ¶
外部Icebergカタログを使用するIcebergテーブルを作成する場合、Icebergの数値型は次の表に従ってSnowflakeの数値型にマッピングされます。
Icebergデータ型 |
Snowflakeデータ型 |
|---|---|
|
|
|
|
|
|
|
|
|
注釈
float や double を主キーとして使用することはできません(Apache Iceberg仕様 に準拠)。
その他のデータ型¶
注釈
数値以外のデータ型については、カタログとしてSnowflakeを使用する場合、テーブル DDL で、Snowflakeデータ型を指定します(例えば、 list 型の代わりに構造化 ARRAY を使用します)。Snowflakeは、外部Icebergツールとの相互運用性のために、各Snowflakeタイプをテーブルメタデータ内の対応するIcebergデータ型に自動的にマッピングします。
Icebergデータ型 |
Snowflakeデータ型 |
注意 |
|---|---|---|
|
||
|
||
|
Apache Icebergテーブルの仕様に従ったマイクロ秒精度。 |
|
|
Apache Icebergテーブルの仕様に従ったマイクロ秒精度。 タイムスタンプには、Parquet物理タイプ |
|
|
Apache Icebergテーブルの仕様に従ったマイクロ秒精度。 タイムスタンプには、Parquet物理タイプ |
|
|
デフォルトのサイズは128 MB で、明示的に指定できるサイズは134217728(128 MB)のみです。 |
|
|
||
|
構造化型列は最大1000個のサブ列をサポートします。 |
|
|
構造化型列は最大1000個のサブ列をサポートします。 |
|
|
構造化型列は最大1000個のサブ列をサポートします。 |
Iceberg v3データ型¶
重要
Iceberg v3データ型を使用するには、Icebergテーブルが準拠するApache Iceberg™仕様のバージョンを:code:`3`として指定する必要があります。バージョンの指定方法について詳しくは、:ref:`tables-iceberg-configuring-default-version`を参照してください。
次の表は、Icebergテーブルで使用できる|iceberg-tm|v3データ型を示しています。
Icebergデータ型 |
Snowflakeデータ型 |
注意 |
|---|---|---|
|
|
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です。 |
|
|
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が必要です。 |
|
|
Apache Icebergテーブル仕様に基づくナノ秒精度。タイムゾーンのセマンティクスなし(ウォールクロック)。TIMESTAMP(9)は最初、Snowflakeパラメーター:ref:`label-timestamp_type_mapping`の値に応じて、TIMESTAMP_NTZ(9)またはTIMESTAMP_LTZ(9)のSnowflake型にマップされます。その後、適切なIcebergデータ型にマッピングされます。 |
|
|
Apache Icebergテーブル仕様に基づくナノ秒精度。UTCとして保存されます。 TIMESTAMP(9)は最初、Snowflakeパラメーター:ref:`label-timestamp_type_mapping`の値に応じて、TIMESTAMP_NTZ(9)またはTIMESTAMP_LTZ(9)のSnowflake型にマップされます。その後、適切なIcebergデータ型にマッピングされます。 |
|
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、バケット、年、月、日、時間など)は、マイクロ秒バリアントとまったく同じように、新しいナノ秒型を受け入れます。
互換性
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)');
GEOGRAPHY値を明示的に作成せずに、地理空間データを挿入することもできます。
INSERT INTO geog_points
SELECT 'POINT(-122.3861109 37.61637595)';
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;
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;
GEOMETRY列にデータを挿入するには、入力データを指定します。次の例では、Well-Known Text(WKT)として定義された地理空間オブジェクトを、前の例で作成した``geo_points``テーブルの``geom``列に挿入します。
INSERT INTO geo_points
SELECT TO_GEOMETRY('POINT(-122.3861109 37.61637595)');
GEOMETRY値を明示的に作成せずに、地理空間データを挿入することもできます。
INSERT INTO geo_points
SELECT 'POINT(-122.3861109 37.61637595)';
SRIDがGEOMETRYオブジェクトの一部として使用できない場合は、コンストラクター関数を使用して明示的に設定できます。
INSERT INTO geo_points
SELECT TO_GEOMETRY('POINT(-122.3861109 37.61637595)', 4326);
ナノ秒のタイムスタンプ¶
次の例では、ナノ秒のタイムスタンプを持つマネージドIcebergテーブルを作成します。
CREATE ICEBERG TABLE sensor_readings (
reading_ntz TIMESTAMP_NTZ(9),
reading_ltz TIMESTAMP_LTZ(9))
ICEBERG_VERSION = 3;
このステートメントに対して、Snowflakeは次のデータ型マッピングを実行します。
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;
同様に、次の例では、カタログリンクのデータベースに空の外部管理Icebergテーブルを作成し、Snowflakeが書き込みを行えるようにします。
USE DATABASE my_catalog_linked_db;
USE SCHEMA my_namespace;
CREATE ICEBERG TABLE car_sales (record VARIANT)
ICEBERG_VERSION = 3;
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"]}
]
}'
);
テーブルで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;
出力:
+-------------------------+
| RECORD:SALESPERSON.NAME |
|-------------------------|
| "John Salesperson" |
+-------------------------+
半構造化データのクエリについて詳しくは、: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()
同様に、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));
デルタデータ型¶
次の表は、 デルタテーブルファイルから作成された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 物理タイプ |
TIMESTAMP_NTZ |
TIMESTAMP_NTZ(6) |
次の表は、デルタ入れ子データ型がSnowflakeデータ型にどのようにマッピングされるかを示しています。
デルタ入れ子型 |
Snowflakeデータ型 |
|---|---|
STRUCT |
|
ARRAY |
|
MAP |
考慮事項¶
Icebergテーブルのデータ型で作業する場合、次の項目を考慮してください。
次のIcebergデータ型を使用する列を持つ テーブルの変換 はサポートされていません。
uuidfixed(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では作成できません。
floatやdoubleを主キーとして使用することはできません(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をサポートしていません。