Tipos de dados para tabelas Apache Iceberg™

O Snowflake oferece suporte à maioria dos tipos de dados definidos pela especificação Apache Iceberg™ e grava tipos de dados Iceberg em arquivos de tabela para que suas tabelas Iceberg permaneçam interoperáveis entre diferentes mecanismos de computação quando você usa o Snowflake como catálogo.

Para obter uma visão geral dos tipos de dados Iceberg compatíveis com o Snowflake, consulte Tipos de dados suportados.

Tipos aproximados

Se a sua tabela usar um tipo de dados Iceberg para o qual o Snowflake não oferece suporte a uma correspondência exata, o Snowflake usará um tipo Snowflake aproximado. Esse mapeamento de tipo afeta os valores das colunas para tabelas convertidas e tabelas Iceberg que usam Snowflake como catálogo.

Por exemplo, considere uma tabela com uma coluna do tipo Iceberg int. Snowflake processa os valores da coluna usando o tipo de dados Snowflake NUMBER(10,0).

NUMBER(10,0) tem um intervalo de (-9.999.999.999, +9.999.999.999), mas int tem um intervalo mais limitado de (-2.147.483.648, +2.147.483.647). Se você tentar inserir um valor de 3.000.000.000 nessa coluna, o Snowflake retornará uma mensagem de erro fora do intervalo.

Para obter detalhes sobre tipos aproximados, consulte as notas na tabela Tipos de dados suportados.

Tipos de dados suportados

As tabelas nesta seção mostram a relação entre os tipos de dados Iceberg e os tipos de dados Snowflake. Elas usam as seguintes colunas:

Tipo Iceberg:

O tipo de dados definido na especificação Apache Iceberg. Quando você usa o Snowflake como catálogo, o Snowflake grava o tipo Iceberg nos arquivos de dados da tabela para que as tabelas permaneçam interoperáveis entre diferentes mecanismos de computação.

Tipo de dados Snowflake:

O tipo de dados Snowflake usado para processar e retornar dados da tabela. Por exemplo, se seu esquema especificar o tipo Iceberg timestamp, o Snowflake processará e retornará valores usando o tipo de dados Snowflake TIMESTAMP_NTZ(6) com precisão de microssegundos.

Notas:

Notas de uso adicionais, incluindo notas para trabalhar com tipos aproximados.

Tipos numéricos

Snowflake como catálogo

A tabela a seguir mostra como os tipos de dados numéricos Iceberg são mapeados para os tipos de dados numéricos do Snowflake para tabelas que usam o Snowflake como o catálogo Iceberg (tabelas gerenciadas pelo Snowflake). Ao criar uma tabela Iceberg gerenciada pelo Snowflake, você pode usar os tipos de dados Iceberg para definir colunas numéricas.

Tipo de dados Iceberg

Tipo de dados do Snowflake

Notas

int (inteiro assinado de 32 bits)

NUMBER(10,0)

Inserir um número de 10 dígitos menor que o mínimo ou maior que o valor inteiro assinado de 32 bits máximo resulta em um erro fora do intervalo.

long (inteiro assinado de 64 bits)

NUMBER(19,0)

Inserir um número de 19 dígitos menor que o mínimo ou maior que o valor inteiro assinado de 64 bits máximo resulta em um erro fora do intervalo.

float (ponto flutuante precisão única 32 bits IEEE 754)

FLOAT

Sinônimo do tipo de dados Snowflake DOUBLE. Snowflake trata todos os números de ponto flutuante como números de ponto flutuante de 64 bits de precisão dupla, mas grava os números flutuantes Iceberg como números de ponto flutuante de 32 bits em arquivos de dados de tabela.

Reduzir as conversões de 64 bits para 32 bits resulta em perda de precisão.

Você não pode usar float ou double como chaves primárias (de acordo com o especificação do Apache Iceberg).

double (ponto flutuante de precisão dupla 64 bits IEEE 754)

FLOAT

Sinônimo do tipo de dados Snowflake DOUBLE. Snowflake trata todos os números de ponto flutuante como números de ponto flutuante de 64 bits de precisão dupla.

Reduzir as conversões de 64 bits para 32 bits resulta em perda de precisão.

Você não pode usar float ou double como chaves primárias (de acordo com o especificação do Apache Iceberg).

decimal(P,S)

NUMBER(P,S)

Especificar decimal(10,0) em vez de int cria um tipo decimal em Iceberg. O mesmo se aplica quando você especifica decimal(19,0).

Catálogo externo

Quando você cria uma tabela Iceberg que usa um catálogo Iceberg externo, os tipos numéricos Iceberg são mapeados para tipos numéricos Snowflake de acordo com a tabela a seguir.

Tipo de dados Iceberg

Tipo de dados do Snowflake

int (inteiro assinado de 32 bits)

NUMBER(10,0)

long (inteiro assinado de 64 bits)

NUMBER(19,0)

float (ponto flutuante precisão única 32 bits IEEE 754)

FLOAT

double (ponto flutuante de precisão dupla 64 bits IEEE 754)

FLOAT

decimal(P,S)

NUMBER(P,S)

Nota

Você não pode usar float ou double como chaves primárias (de acordo com o especificação do Apache Iceberg).

Outros tipos de dados

Nota

Para tipos de dados não numéricos, especifique o tipo de dados Snowflake em sua tabela DDL ao usar o Snowflake como catálogo (por exemplo, use um ARRAY estruturado em vez do tipo list). O Snowflake mapeia automaticamente cada tipo Snowflake para o tipo de dados Iceberg correspondente nos metadados da tabela para interoperabilidade com ferramentas Iceberg externas.

Tipo de dados Iceberg

Tipo de dados do Snowflake

Notas

boolean

BOOLEAN

date

DATE

time

TIME(6)

Precisão de microssegundos conforme especificação da tabela Apache Iceberg.

timestamp

TIMESTAMP_NTZ(6)

Precisão de microssegundos conforme especificação da tabela Apache Iceberg.

Você também pode usar o tipo físico Parquet int96 para carimbos de data/hora. O Snowflake traduz timestamp para microssegundos (conforme a especificação da tabela Apache Iceberg).

timestamptz

TIMESTAMP_LTZ(6)

Precisão de microssegundos conforme especificação da tabela Apache Iceberg.

Você também pode usar o tipo físico Parquet int96 para carimbos de data/hora. O Snowflake traduz timestamp para microssegundos (conforme a especificação da tabela Apache Iceberg).

string

VARCHAR(134217728)

O tamanho padrão é 128 MB, e o único tamanho que você pode especificar explicitamente é 134217728 (128 MB).

uuid

UUID

struct

OBJECT estruturado

Colunas de tipo estruturado suportam no máximo 1.000 subcolunas.

list

ARRAY estruturada

Colunas de tipo estruturado suportam no máximo 1.000 subcolunas.

map

MAP

Colunas de tipo estruturado suportam no máximo 1.000 subcolunas.

Tipos de dados do Iceberg v3

Importante

Para usar os tipos de dados do Iceberg v3, você deve especificar a versão da especificação Apache Iceberg™ com a qual sua tabela Iceberg está em conformidade como 3. Para obter instruções sobre como especificar uma versão, consulte Configuração da versão padrão do Iceberg.

A tabela a seguir mostra os tipos de dados do Apache Iceberg™ v3 que você pode usar com tabelas Iceberg:

Tipo de dados Iceberg

Tipo de dados do Snowflake

Notas

geography

GEOGRAPHY

O Snowflake oferece suporte a Tipo de dados GEOGRAPHY nas tabelas Apache Iceberg™. Você pode criar uma tabela Iceberg gerenciada pelo Snowflake ou externamente com uma coluna GEOGRAPHY. Para criar uma tabela Iceberg com uma coluna GEOGRAPHY, use o comando CREATE ICEBERG TABLE.

Cuidado

O Iceberg usa o formato WKB para armazenar dados de geografia. Esse formato não pode representar todos os dados que podem ser contidos nos valores GEOGRAPHY do Snowflake. Os tipos Feature e FeatureCollection não são compatíveis com o formato WKB. Ao inserir valores GEOGRAPHY com esses tipos em uma tabela Iceberg, o Snowflake converte os recursos em seus objetos de geografia subjacentes e descarta todas as propriedades. A conversão automática de tabelas Iceberg se comporta de forma idêntica à da função ST_ASWKB.

Para objetos GEOGRAPHY, o SRID é sempre 4326.

geometry

GEOMETRY

O Snowflake oferece suporte a Tipo de dados GEOMETRY nas tabelas Apache Iceberg™. Você pode criar uma tabela Iceberg gerenciada pelo Snowflake ou externamente com uma coluna GEOMETRY. Para criar uma tabela Iceberg com uma coluna GEOMETRY, use o comando CREATE ICEBERG TABLE.

Nota

Todos os objetos GEOMETRY em uma única coluna devem ter o mesmo SRID.

timestamp_ns

TIMESTAMP_NTZ(9)

Precisão de nanossegundos conforme especificação da tabela Apache Iceberg. Sem semântica de fuso horário (relógio de parede). Primeiro, TIMESTAMP(9) é mapeado para o tipo TIMESTAMP_NTZ(9) ou TIMESTAMP_LTZ(9) do Snowflake, dependendo do valor do parâmetro TIMESTAMP_TYPE_MAPPING do Snowflake. Em seguida, ele é mapeado para o tipo de dados do Iceberg apropriado.

timestamptz_ns

TIMESTAMP_LTZ(9)

Precisão de nanossegundos conforme especificação da tabela Apache Iceberg. Armazenada em UTC.

Primeiro, TIMESTAMP(9) é mapeado para o tipo TIMESTAMP_NTZ(9) ou TIMESTAMP_LTZ(9) do Snowflake, dependendo do valor do parâmetro TIMESTAMP_TYPE_MAPPING do Snowflake. Em seguida, ele é mapeado para o tipo de dados do Iceberg apropriado.

variant

VARIANT

Inicialmente, a Snowflake desenvolveu o tipo de dados VARIANT para tabelas padrão do Snowflake.

VARIANT fornece uma codificação binária eficiente para dados semiestruturados dinâmicos, comoJSON, Avro e Protobuf, o que facilita o trabalho e a operação usando dados que contêm outros tipos de dados aninhados. Para obter mais informações, consulte Tipos de dados semiestruturados e Introduction to loading semi-structured data.

Fragmentação

O Snowflake oferece fragmentação interna (também chamada de subcolunarização) para o tipo de dados VARIANT. A fragmentação é o processo de extrair campos de uma coluna do tipo VARIANT em campos separados e armazenar cada campo em forma de coluna (subcolunas) que você pode percorrer e consultar usando uma notação especial.

O Snowflake rastreia metadados e estatísticas de subcolunas fragmentadas, o que permite a remoção para consultas mais rápidas e eficientes.

Quando você insere dados semiestruturados em uma coluna VARIANT, o Snowflake fragmenta o máximo de dados possível.

Para obter mais informações, consulte Arquivos de dados semiestruturados e subcolunarização.

Considerações sobre os tipos de dados do Iceberg v3

Considere o seguinte ao usar os tipos de dados do Iceberg v3:

Carimbos de data/hora em nanossegundos

  • Notas de uso para o tipo de dados nanosecond timestamps:

    • Use TIMESTAMP_NTZ(9), TIMESTAMP_LTZ(9) ou TIMESTAMP(9) nas instruções CREATE ICEBERG TABLE e ALTER ICEBERG TABLE. Uma escala de 9 especifica um novo tipo de nanossegundo do Iceberg. Uma escala de 6 continua a especificar o tipo de microssegundo legado.

    • Quando uma escala é omitida, o parâmetro no nível da sessão ICEBERG_TIMESTAMP_DEFAULT_SCALE controla a precisão. O padrão permanece 6 para compatibilidade. Se você quiser que as colunas de carimbo de data/hora Iceberg sejam configuradas como nanossegundos por padrão, defina o parâmetro como 9.

    • Todas as transformações de partição Iceberg padrão (por exemplo, identidade, bucket, ano, mês, dia e hora) aceitam os novos tipos de nanossegundos exatamente da mesma forma que aceitam as variantes de microssegundos.

    • Compatibilidade

      • Leitura/gravação: operações de leitura e gravação são compatíveis com tabelas Iceberg gerenciadas pelo Snowflake e externamente.

      • Ferramentas externas: não são necessárias alterações no conector. Os valores de nanossegundos são usados em operações de leitura e gravação como os valores timestamp_ns e:code:timestamptz_ns padrão do Iceberg.

VARIANT

  • Observe as seguintes considerações e limitações ao usar o tipo de dados VARIANT com tabelas Iceberg:

Exemplos

A seção a seguir contém exemplos para os tipos de dados do Iceberg v3.

GEOGRAPHY

Para inserir dados em uma coluna GEOGRAPHY, especifique os dados de entrada. O exemplo a seguir insere um objeto geoespacial que é definido como texto bem conhecido (Well-Known Text, WKT) na coluna geog da tabela geog_points que foi criada no exemplo anterior:

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

Você também pode inserir dados geoespaciais sem construir explicitamente o valor GEOGRAPHY:

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

O exemplo a seguir cria uma tabela Iceberg vazia que contém uma única coluna GEOMETRY chamada geom com o SRID padrão 4326.

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

Você também pode definir o SRID explicitamente na instrução DDL. O exemplo a seguir define o SRID como 4269:

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

Para inserir dados em uma coluna GEOMETRY, especifique os dados de entrada. O exemplo a seguir insere um objeto geoespacial definido como texto bem conhecido (Well-Known Text, WKT) na coluna geom da tabela geo_points que foi criada no exemplo anterior.

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

Você também pode inserir dados geoespaciais sem construir explicitamente o valor GEOMETRY:

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

Se o SRID não estiver disponível como parte do objeto GEOMETRY, você poderá defini-lo explicitamente usando a função de construtor:

INSERT INTO geo_points
  SELECT TO_GEOMETRY('POINT(-122.3861109 37.61637595)', 4326);
Copy
carimbos de data/hora em nanossegundos

O exemplo a seguir cria uma tabela Iceberg gerenciada com carimbos de data/hora em nanossegundos:

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

Para esta instrução, o Snowflake realiza os seguintes mapeamentos de tipos de dados:

  • O tipo de dados da coluna reading_ntz é mapeado para o tipo de dados timestamp_ns do Iceberg v3.

  • O tipo de dados da coluna reading_ltz é mapeado para o tipo de dados timestamptz_ns do Iceberg v3.

VARIANT

Você pode criar uma tabela Iceberg com uma coluna VARIANT usando o comando CREATE ICEBERG TABLE.

O exemplo a seguir cria uma tabela Iceberg gerenciada pelo Snowflake vazia que contém uma única coluna VARIANT chamada record.

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

Da mesma forma, o exemplo a seguir cria uma tabela Iceberg gerenciada externamente vazia em um banco de dados vinculado a catálogo, na qual o Snowflake pode gravar.

USE DATABASE my_catalog_linked_db;

USE SCHEMA my_namespace;

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

Para inserir dados em uma coluna VARIANT, você especifica o formato dos dados de entrada. O exemplo a seguir usa a função PARSE_JSON para inserir dados formatados em JSON na coluna record da tabela car_sales (criada anteriormente).

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

A execução de uma instrução SELECT * FROM na tabela retorna a seguinte saída:

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

Para consultar os dados em uma coluna VARIANT, é possível usar a notação de ponto ou de colchete para acessar os elementos aninhados nos dados.

O exemplo a seguir usa a notação de ponto para obter os nomes de todos os vendedores que venderam carros. Como há uma linha na tabela, a consulta produz um único valor de resultado.

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

Saída:

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

Para obter mais informações sobre a consulta de dados semiestruturados, consulte Consulta de dados semiestruturados.

Nota

  • Ao usar o Apache Spark para ler ou gravar tabelas Iceberg com colunas Variant, é necessário usar o Apache Spark 4.0 ou mais recente, que seja compatível com Variant.

    As colunas Variant em tabelas Iceberg gerenciadas pelo Snowflake podem ser lidas por mecanismos compatíveis com Variant do Iceberg, como o Apache Spark. Os mecanismos podem ler as tabelas Iceberg v3 gerenciadas pelo Snowflake por meio da API REST Horizon Iceberg 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

    Da mesma forma, o Snowflake pode ler ou gravar em tabelas Iceberg gerenciadas externamente que tenham colunas Variant.

  • O Snowflake pode gravar valores nulos em uma tabela, se necessário.

    Por exemplo:

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

Tipos de dados Delta

A tabela a seguir mostra como os tipos de dados Delta são mapeados para os tipos de dados Snowflake para tabelas Iceberg criadas a partir de arquivos de tabela Delta.

Tipo Delta

Tipo de dados do Snowflake

Observação

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)

Você também pode usar o tipo físico Parquet int96 para TIMESTAMP, mas o Snowflake não oferece suporte a int96 para TIMESTAMP_NTZ.

TIMESTAMP_NTZ

TIMESTAMP_NTZ(6)

A tabela a seguir mostra como os tipos de dados Delta aninhados são mapeados para os tipos de dados do Snowflake.

Tipo Delta aninhado

Tipo de dados do Snowflake

STRUCT

OBJECT estruturado

ARRAY

ARRAY estruturado

MAP

MAP

Considerações

Considere os itens a seguir ao trabalhar com tipos de dados para tabelas Iceberg:

  • Não há suporte para a conversão de uma tabela com colunas que usam os seguintes tipos de dados Iceberg:

    • uuid

    • fixed(L)

  • Para tabelas que usam Snowflake como catálogo, não há suporte para a criação de uma tabela que use o tipo de dados Iceberg uuid.

  • Para tabelas que usam um catálogo externo, não é possível criar tabelas Iceberg v3 com colunas de tipo estruturado, o que inclui OBJECT, ARRAY ou MAP. Por exemplo, não é possível usar CREATE ICEBERG TABLE … AS SELECT (CTAS) para criar uma tabela Iceberg v3 gerenciada externamente com colunas de tipo estruturado.

    É possível criar tabelas Iceberg v3 gerenciadas pelo Snowflake com colunas de tipo estruturado.

  • Para todos os tipos de tabela Iceberg:

    • Colunas de tipo estruturado suportam no máximo 1.000 subcolunas.

    • Iceberg oferece suporte à precisão de microssegundos para tipos de hora e carimbo de data/hora. Como resultado, você não pode criar uma tabela Iceberg no Snowflake que use outra precisão, como milissegundo ou nanossegundo.

    • Você não pode usar float ou double como chaves primárias (de acordo com o especificação do Apache Iceberg).

    • Para arquivos Parquet que usam o tipo lógico LIST, esteja ciente do seguinte:

      • A estrutura de anotação de três níveis com a palavra-chave element é compatível. Para obter mais informações, consulte Definições do tipo lógico Parquet. Se o arquivo Parquet usar um formato obsoleto com a palavra-chave array, você deverá gerar novamente os dados com base no formato compatível.

  • Para tabelas criadas a partir de arquivos Delta, esteja ciente do seguinte:

    • Arquivos Parquet (arquivos de dados para tabelas Delta) que usam qualquer um dos seguintes recursos ou tipos de dados não são compatíveis:

      • Campo IDs.

      • O tipo de dados INTERVAL.

      • O tipo de dados DECIMAL com precisão maior que 38.

      • Os tipos LIST ou MAP com representação de um ou dois níveis.

      • Tipos inteiros sem sinal (INT(signed = false)).

      • O tipo de dados FLOAT16.

    • Você pode usar o tipo físico Parquet int96 para TIMESTAMP, mas o Snowflake não oferece suporte a int96 para TIMESTAMP_NTZ.