Types de données des tables Apache Iceberg™

Snowflake prend en charge la plupart des types de données définis par la spécification Apache Iceberg™, et écrit les types de données Iceberg dans les fichiers de table afin que vos tables Iceberg restent interopérables entre les différents moteurs de calcul lorsque vous utilisez Snowflake comme catalogue.

Pour une vue d’ensemble des types de données Iceberg pris en charge par Snowflake, voir Types de données pris en charge.

Types approximatifs

Si votre table utilise un type de données Iceberg pour lequel Snowflake ne prend pas en charge une correspondance exacte, Snowflake utilise un type Snowflake approximatif. Ce type de mappage affecte les valeurs des colonnes des tables converties et des tables Iceberg qui utilisent Snowflake comme catalogue.

Prenons l’exemple d’une table comportant une colonne de type Iceberg int. Snowflake traite les valeurs des colonnes en utilisant le type de données Snowflake NUMBER(10,0).

NUMBER(10,0) a une plage de (-9,999,999,999, +9,999,999,999), mais int a une plage plus limitée de (-2,147,483,648, +2,147,483,647). Si vous essayez d’insérer une valeur 3,000,000,000 dans cette colonne, Snowflake renvoie un message d’erreur hors plage.

Pour plus de détails sur les types approximatifs, voir les notes dans le tableau Types de données pris en charge.

Types de données pris en charge

Le tableau dans cette section montre la relation entre les types de données Iceberg et les types de données Snowflake. Les colonnes suivantes sont utilisées :

Type Iceberg:

Type de données défini dans la spécification Apache Iceberg. Lorsque vous utilisez Snowflake comme catalogue, Snowflake écrit le type Iceberg dans les fichiers de données des tables afin que celles-ci restent interopérables entre les différents moteurs de calcul.

Type Snowflake:

Type de données Snowflake utilisé pour traiter et renvoyer les données de table. Par exemple, si votre schéma spécifie le type Iceberg timestamp, Snowflake traite et renvoie des valeurs utilisant le type de données Snowflake TIMESTAMP_NTZ(6) à une précision de l’ordre de la microseconde.

Remarques:

Notes sur l’utilisation supplémentaires, notamment pour utiliser les types approximatifs.

Types numériques

Snowflake comme catalogue

Le tableau suivant montre comment les types de données numériques Iceberg mappent les types de données numériques Snowflake pour les tables qui utilisent Snowflake comme catalogue Iceberg (tables gérées par Snowflake). Lorsque vous créez une table Iceberg gérée par Snowflake, vous pouvez utiliser les types de données Iceberg pour définir les colonnes numériques.

Type de données Iceberg

Type de données Snowflake

Remarques

int (entier signé de 32 bits)

NUMBER(10,0)

L’insertion d’un nombre à 10 chiffres inférieur à la valeur minimale ou supérieur à la valeur maximale d’un entier signé de 32 bits entraîne une erreur hors plage.

long (entier signé de 64 bits)

NUMBER(19,0)

L’insertion d’un nombre à 19 chiffres inférieur à la valeur minimale ou supérieur à la valeur maximale d’un entier signé de 64 bits entraîne une erreur hors plage.

float (virgule flottante IEEE 754 de 32 bits simple précision)

FLOAT

Synonyme du type de données DOUBLE Snowflake. Snowflake traite tous les nombres à virgule flottante comme des nombres à virgule flottante de 64 bits double précision, mais écrit les nombres à virgule flottante Iceberg comme des nombres à virgule flottante de 32 bits dans les fichiers de données des tables.

Le fait de réduire les conversions de 64 bits à 32 bits entraîne une perte de précision.

Vous ne pouvez pas utiliser float ni double comme clés primaires (conformément à la spécification Apache Iceberg).

double (virgule flottante IEEE 754 de 64 bits double précision)

FLOAT

Synonyme du type de données DOUBLE Snowflake. Snowflake traite tous les nombres à virgule flottante comme des nombres à virgule flottante de 64 bits double précision.

Le fait de réduire les conversions de 64 bits à 32 bits entraîne une perte de précision.

Vous ne pouvez pas utiliser float ni double comme clés primaires (conformément à la spécification Apache Iceberg).

decimal(P,S)

NUMBER(P,S)

En spécifiant decimal(10,0) au lieu de int , vous créez un type décimal dans Iceberg. Il en va de même lorsque vous spécifiez decimal(19,0).

Catalogue externe

Lorsque vous créez une table Iceberg qui utilise un catalogue Iceberg externe, les types numériques Iceberg sont mappés aux types numériques Snowflake selon le tableau suivant.

Type de données Iceberg

Type de données Snowflake

int (entier signé de 32 bits)

NUMBER(10,0)

long (entier signé de 64 bits)

NUMBER(19,0)

float (virgule flottante IEEE 754 de 32 bits simple précision)

FLOAT

double (virgule flottante IEEE 754 de 64 bits double précision)

FLOAT

decimal(P,S)

NUMBER(P,S)

Note

Vous ne pouvez pas utiliser float ni double comme clés primaires (conformément à la spécification Apache Iceberg).

Autres types de données

Note

Pour les types de données non numériques, spécifiez le type de données Snowflake dans l’instruction DDL de votre table lorsque vous utilisez Snowflake comme catalogue (par exemple, utilisez un ARRAY structuré au lieu du type list). Snowflake mappe automatiquement chaque type de données Snowflake au type de données Iceberg correspondant dans les métadonnées de table pour assurer l’interopérabilité avec les outils Iceberg externes.

Type de données Iceberg

Type de données Snowflake

Remarques

boolean

BOOLEAN

date

DATE

time

TIME(6)

Précision à la microseconde selon les spécifications de la table Apache Iceberg.

timestamp

TIMESTAMP_NTZ(6)

Précision à la microseconde selon les spécifications de la table Apache Iceberg.

Vous pouvez également utiliser le type physique Parquet int96 pour les horodatages. Snowflake traduit timestamp en microsecondes (conformément aux spécifications de la table Apache Iceberg).

timestamptz

TIMESTAMP_LTZ(6)

Précision à la microseconde selon les spécifications de la table Apache Iceberg.

Vous pouvez également utiliser le type physique Parquet int96 pour les horodatages. Snowflake traduit timestamp en microsecondes (conformément aux spécifications de la table Apache Iceberg).

string

VARCHAR(134217728)

La taille par défaut est 128 MB, et la seule taille que vous pouvez spécifier explicitement est 134217728 (128 MB).

uuid

UUID

struct

OBJECT structuré

Les colonnes de type structuré prennent en charge un maximum de 1 000 sous-colonnes.

list

ARRAY structuré

Les colonnes de type structuré prennent en charge un maximum de 1 000 sous-colonnes.

map

MAP

Les colonnes de type structuré prennent en charge un maximum de 1 000 sous-colonnes.

Types de données Iceberg v3

Important

Pour utiliser les types de données Iceberg v3, vous devez spécifier la version de la spécification Apache Iceberg™ à laquelle votre table Iceberg est conforme comme 3. Pour savoir comment spécifier une version, voir Configurer la version Iceberg par défaut.

Le tableau suivant présente les types de données v3 Apache Iceberg™ que vous pouvez utiliser avec les tables Iceberg :

Type de données Iceberg

Type de données Snowflake

Remarques

geography

GEOGRAPHY

Snowflake prend en charge la Type de données GEOGRAPHY dans les tables Apache Iceberg™. Vous pouvez créer une table Iceberg gérée par Snowflake ou en externe avec une colonne GEOGRAPHY. Pour créer une table Iceberg avec une colonne GEOGRAPHY, utilisez la commande CREATE ICEBERG TABLE.

Prudence

Iceberg utilise le format WKB pour stocker des données géographiques. Ce format ne peut pas représenter toutes les données qui peuvent être contenues dans les valeurs GEOGRAPHY Snowflake. Les types Feature et FeatureCollection ne sont pas pris en charge au format WKB. Lors de l’insertion des valeurs GEOGRAPHY avec ces types dans une table Iceberg, Snowflake convertit les fonctionnalités en objets géographiques sous-jacents et supprime toutes les propriétés. La conversion automatique pour les tables Iceberg se comporte de la même manière que la fonction ST_ASWKB.

Pour les objets GEOGRAPHY, le SRID est toujours 4326.

geometry

GEOMETRY

Snowflake prend en charge la Type de données GEOMETRY dans les tables Apache Iceberg™. Vous pouvez créer une table Iceberg gérée par Snowflake ou en externe avec une colonne GEOMETRY. Pour créer une table Iceberg avec une colonne GEOMETRY, utilisez la commande CREATE ICEBERG TABLE.

Note

Tous les objets GEOMETRY d’une seule colonne doivent avoir le même SRID.

timestamp_ns

TIMESTAMP_NTZ(9)

Précision à la nanoseconde selon les spécifications de la table Apache Iceberg. Pas de prise en compte du fuseau horaire (temps réel). TIMESTAMP(9) est d’abord mappé vers le type Snowflake TIMESTAMP_NTZ(9) ou TIMESTAMP_LTZ(9), en fonction de la valeur du paramètre Snowflake TIMESTAMP_TYPE_MAPPING. Ensuite, il est mappé vers le type de données Iceberg approprié.

timestamptz_ns

TIMESTAMP_LTZ(9)

Précision à la nanoseconde selon les spécifications de la table Apache Iceberg. Enregistré en UTC.

TIMESTAMP(9) est d’abord mappé vers le type Snowflake TIMESTAMP_NTZ(9) ou TIMESTAMP_LTZ(9), en fonction de la valeur du paramètre Snowflake TIMESTAMP_TYPE_MAPPING. Ensuite, il est mappé vers le type de données Iceberg approprié.

variant

VARIANT

Snowflake a initialement développé le type de données VARIANT pour les tables standard de Snowflake.

VARIANT fournit un codage binaire efficace pour les données semi-structurées dynamiques telles que JSON, Avro, Protobuf, ce qui facilite le travail et l’exploitation de données contenant d’autres types de données imbriqués. Pour plus d’informations, voir Types de données semi-structurées et Introduction to loading semi-structured data.

Décomposition des données (shredding)

Snowflake fournit un shredding intégré (également appelé sous-colonnarisation) pour les type de données VARIANT. Le shredding consiste à extraire les champs d’une colonne de type VARIANT en champs distincts, puis à stocker chaque champ sous forme de colonnes (sous-colonnes) que l’on peut parcourir et interroger à l’aide d’une notation spécifique.

Snowflake suit les métadonnées et les statistiques des sous-colonnes décomposées, ce qui permet un nettoyage pour des requêtes plus rapides et plus efficaces.

Lorsque vous insérez des données semi-structurées dans une colonne VARIANT, Snowflake décompose autant de données que possible.

Pour plus d’informations, voir Fichiers de données semi-structurées et création de sous-colonnes.

Considérations relatives aux types de données Iceberg v3

Tenez compte des éléments suivants lorsque vous utilisez les types de données Iceberg v3 :

Horodatages à la nanoseconde

  • Notes sur l’utilisation du type de données nanosecond timestamps :

    • Utilisez TIMESTAMP_NTZ(9), TIMESTAMP_LTZ(9) ou TIMESTAMP(9) dans les instructions CREATE ICEBERG TABLE et ALTER ICEBERG TABLE. Une échelle de 9 spécifie un nouveau type de nanosecondes Iceberg. Une échelle de 6 continue de spécifier le type de microseconde existant.

    • Lorsqu’une échelle est omise, le paramètre au niveau de la session ICEBERG_TIMESTAMP_DEFAULT_SCALE contrôle la précision. La valeur par défaut reste 6 pour la compatibilité. Si vous souhaitez que les colonnes d’horodatage Iceberg soient définies par défaut sur des nanosecondes, définissez le paramètre sur 9.

    • Toutes les transformations de partition standard d’Iceberg (par exemple, identité, compartiment, année, mois, jour et heure) prennent en charge les nouveaux types en nanosecondes exactement de la même manière que les variantes en microsecondes.

    • Compatibilité

      • Lire/écrire - Les opérations de lecture et d’écriture sont prises en charge à la fois pour les tables Iceberg gérées par Snowflake et celles gérées en externe.

      • Outils externes - Aucun changement de connecteur n’est nécessaire. Les valeurs nanosecondes sont utilisées dans les opérations de lecture et d’écriture selon les valeurs timestamp_ns et timestamptz_ns Iceberg standard.

VARIANT

  • Tenez compte des considérations et des limites suivantes lorsque vous utilisez le type de données VARIANT avec les tables Iceberg :

Exemples

La section suivante contient des exemples pour les types de données Iceberg v3.

GEOGRAPHY

Pour insérer des données dans une colonne GEOGRAPHY, spécifiez les données d’entrée. L’exemple suivant insère un objet géospatial défini comme du texte bien connu (WKT) dans la colonne geog de la table geog_points créée dans l’exemple précédent :

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

Vous pouvez également insérer des données géospatiales sans créer explicitement la valeur GEOGRAPHY :

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

L’exemple suivant crée une table Iceberg vide contenant une seule colonne GEOMETRY nommée geom avec un SRID par défaut de 4326.

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

Vous pouvez également définir un SRID explicitement dans l’instruction DDL. L’exemple suivant définit le 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

Pour insérer des données dans une colonne GEOMETRY, spécifiez les données d’entrée. L’exemple suivant insère un objet géospatial défini comme du texte bien connu (WKT) dans la colonne geom de la table geo_points créée dans l’exemple précédent.

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

Vous pouvez également insérer des données géospatiales sans créer explicitement la valeur GEOMETRY :

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

Si le SRID n’est pas disponible dans le cadre de l’objet GEOMETRY, vous pouvez le définir explicitement en utilisant la fonction du constructeur :

INSERT INTO geo_points
  SELECT TO_GEOMETRY('POINT(-122.3861109 37.61637595)', 4326);
Copy
horodatages en nanosecondes

L’exemple suivant crée une table Iceberg gérée avec des horodatages en nanosecondes :

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

Pour cette instruction, Snowflake effectue les mappages de types de données suivants :

  • Le type de données de la colonne reading_ntz est mappée avec le type de données Iceberg v3 timestamp_ns.

  • Le type de données de la colonne reading_ltz est mappée avec le type de données Iceberg v3 timestamptz_ns.

VARIANT

Vous pouvez créer une table Iceberg avec une colonne VARIANT en utilisant la commande CREATE ICEBERG TABLE.

L’exemple suivant crée une table Iceberg gérée par Snowflake vide qui contient une seule colonne VARIANT nommée record.

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

De même, l’exemple suivant crée une table Iceberg gérée en externe vide dans une base de données liée au catalogue, dans laquelle Snowflake peut écrire.

USE DATABASE my_catalog_linked_db;

USE SCHEMA my_namespace;

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

Pour insérer des données dans une colonne VARIANT, vous spécifiez le format des données d’entrée. L’exemple suivant utilise la fonction PARSE_JSON pour insérer des données au format JSON dans la colonne record de la table car_sales (créée précédemment).

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

L’exécution d’une instruction SELECT * FROM sur la table renvoie la sortie suivante :

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

Pour interroger les données d’une colonne VARIANT, vous pouvez utiliser les points ou la notation entre crochets pour accéder aux éléments imbriqués dans les données.

L’exemple suivant utilise la notation par points pour récupérer les noms de tous les commerciaux ayant vendu des voitures. Comme il y a une seule ligne dans la table, la requête produit une seule valeur de résultat.

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

Sortie :

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

Vous trouverez plus d’informations sur l’interrogation des données semi-structurées dans Interrogation de données semi-structurées.

Note

  • Lorsque vous utilisez Apache Spark pour lire ou écrire des tables Iceberg avec des colonnes de type Variant, vous devez utiliser Apache Spark 4.0 ou une version ultérieure qui inclut la prise en charge Variant.

    Les colonnes de type Variant dans les tables Iceberg gérées par Snowflake peuvent être lues par des moteurs par les moteurs prenant en charge Iceberg Variant, tels qu’Apache Spark. Les moteurs peuvent lire les tables Iceberg v3 gérées par Snowflake via l’API Horizon Iceberg REST Catalog.

    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

    De même, Snowflake peut lire ou écrire dans des tables Iceberg gérées en externe contenant des colonnes de type Variant.

  • Snowflake peut écrire des valeurs null dans une table, si nécessaire.

    Par exemple :

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

Types de données Delta

Le tableau suivant montre comment les types de données Delta mappent les types de données Snowflake pour les tables Iceberg créées à partir de fichiers de table Delta.

Type Delta

Type de données Snowflake

Remarque

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)

Vous pouvez également utiliser le type physique Parquet int96 pour TIMESTAMP, mais Snowflake ne prend pas en charge le type int96 pour TIMESTAMP_NTZ.

TIMESTAMP_NTZ

TIMESTAMP_NTZ(6)

Le tableau suivant montre comment les types de données imbriqués Delta mappent les types de données Snowflake.

Type imbriqué Delta

Type de données Snowflake

STRUCT

OBJECT structuré

ARRAY

ARRAY structuré

MAP

MAP

Considérations

Tenez compte des éléments suivants lorsque vous utilisez des types de données pour les tables Iceberg :

  • La conversion d’une table dont les colonnes utilisent les types de données Iceberg suivants n’est pas prise en charge :

    • uuid

    • fixed(L)

  • Pour les tables qui utilisent Snowflake comme catalogue, la création d’une table qui utilise le type de données Iceberg uuid n’est pas prise en charge.

  • Pour les tables qui utilisent un catalogue externe, vous ne pouvez pas créer de tables Iceberg v3 avec des colonnes de type structuré, qui incluent OBJECT, ARRAY ou MAP. Par exemple, vous ne pouvez pas utiliser CREATE ICEBERG TABLE … AS SELECT (CTAS) pour créer une table Iceberg v3 gérée en externe avec des colonnes de type structuré.

    Vous pouvez créer des tables Iceberg v3 gérées par Snowflake avec des colonnes de type structuré.

  • Pour tous les types de table Iceberg :

    • Les colonnes de type structuré prennent en charge un maximum de 1 000 sous-colonnes.

    • Iceberg prend en charge la précision à la microseconde pour les types time (temps) et timestamp (horodatage). Par conséquent, vous ne pouvez pas créer une table Iceberg dans Snowflake qui utilise une autre précision comme une précision à la milliseconde ou à la nanoseconde.

    • Vous ne pouvez pas utiliser float ni double comme clés primaires (conformément à la spécification Apache Iceberg).

    • Pour les fichiers Parquet qui utilisent le type logique LIST, tenez compte des points suivants :

      • La structure d’annotation à trois niveaux avec le mot-clé element est prise en charge. Pour plus d’informations, consultez Définitions de types logiques Parquet. Si votre fichier Parquet utilise un format obsolète avec le mot-clé array, vous devez régénérer vos données en vous basant sur le format pris en charge.

  • Pour les tables créées à partir de fichiers Delta, tenez compte des points suivants :

    • Les fichiers Parquet (fichiers de données pour les tables Delta) qui utilisent l’une des fonctionnalités ou l’un des types de données suivants ne sont pas pris en charge :

      • IDs de champ.

      • Le type de données est INTERVAL.

      • Le type de données DECIMAL avec une précision supérieure à 38.

      • Types LIST ou MAP avec représentation à un ou deux niveaux.

      • Types d’entiers non signés (INT(signé = faux)).

      • Le type de données est FLOAT16.

    • Vous pouvez utiliser le type physique Parquet int96 pour TIMESTAMP, mais Snowflake ne prend pas en charge int96 pour TIMESTAMP_NTZ.