Introdução ao carregamento de dados semiestruturados

Este tópico descreve os dados semiestruturados e apresenta informações sobre como carregá-los e armazená-los no Snowflake.

Neste tópico:

O que são dados semiestruturados?

Dados semiestruturados são dados que não estão em conformidade com os padrões dos dados estruturados tradicionais, mas que contêm tags (etiquetas) ou outros tipos de marcação que identificam entidades individuais e distintas dentro dos dados.

Dois dos principais atributos que distinguem os dados semiestruturados dos dados estruturados são as estruturas de dados aninhadas e a ausência de um esquema fixo:

  • Os dados estruturados requerem um esquema fixo que é definido antes que os dados possam ser carregados e consultados em um sistema de banco de dados relacional. Os dados semiestruturados não requerem a definição prévia de um esquema e podem evoluir constantemente (ou seja, é possível acrescentar novos atributos a qualquer momento).

    Além disso, entidades dentro de uma mesma classe podem ter atributos diferentes mesmo que estejam agrupadas, e a ordem dos atributos não é importante.

  • Ao contrário dos dados estruturados, que representam os dados como uma tabela simples, os dados semiestruturados podem conter vários níveis de hierarquias de informações aninhadas.

O que são dados hierárquicos?

Normalmente, os dados semiestruturados são organizados de forma hierárquica. Estruturas de dados complexas podem ser criadas aninhando tipos de dados mais simples, tais como matrizes e objetos. (Obs.: um OBJECT Snowflake corresponde a um “dicionário” ou a um “mapa”. Um objeto Snowflake não é um “objeto” no sentido da “programação orientada a objetos”).

Por exemplo, os dados JSON podem conter um objeto que contém uma matriz. Cada célula dessa matriz pode conter por si só um objeto ou matriz aninhada.

Você pode usar os tipos de dados do Snowflake para criar uma hierarquia para armazenar seus dados semiestruturados usando as seguintes propriedades dos tipos de dados:

  • Um VARIANT pode conter um valor de qualquer outro tipo de dados, incluindo um ARRAY ou um OBJECT.

  • Um ARRAY ou OBJECT contém um valor do tipo VARIANT.

Por exemplo, suponha que você queira armazenar as datas em que ocorreram diferentes tipos de desastres naturais. Você pode criar um OBJECT que contenha as chaves ‘Furacão’, ‘Terremoto’, ‘Inundação’, etc. O valor associado a cada uma dessas chaves pode ser um ARRAY que contém as datas em que cada tipo de desastre ocorreu. Como o valor em cada par chave-valor deve ser um VARIANT, cada matriz de datas seria armazenada como um ARRAY encapsulado em um VARIANT dentro do OBJECT correspondente. O nível superior da hierarquia seria semelhante ao seguinte (as chaves indicam um OBJECT que contém pares chave-valor):

{
    "Flood": flood_date_array::VARIANT,
    "Earthquake": earthquake_date_array::VARIANT,
    ...
}
Copy

Em um outro exemplo, suponha que você queira armazenar uma única lista de desastres em ordem cronológica. Nesse caso, seu tipo de dados externos pode ser ARRAY. Cada célula desse ARRAY pode conter um OBJECT (encapsulado em um VARIANT) que contém pares chave-valor com informações sobre o evento. Por exemplo, cada OBJECT que descreve um terremoto pode ter chaves como ‘Carimbo de data/hora’, ‘Local’ e ‘Magnitude’. Cada OBJECT que descreve um tornado pode ter chaves como ‘Carimbo de data/hora’ e ‘Velocidade_máxima_vento’.

[
    {
        "Event_ID": 54::VARIANT,
        "Type": "Earthquake"::VARIANT,
        "Magnitude": 7.4::VARIANT,
        "Timestamp": "2018-06-09 12:32:15"::TIMESTAMP_LTZ::VARIANT
        ...
    }::VARIANT,
    {
        "Event_ID": 55::VARIANT,
        "Type": "Tornado"::VARIANT,
        "Maximum_wind_speed": 186::VARIANT,
        "Timestamp": "2018-07-01 09:42:55"::TIMESTAMP_LTZ::VARIANT
        ...
    }::VARIANT
]
Copy

Você pode criar hierarquias de dados de quase qualquer profundidade ou amplitude (até o limite de armazenamento de cada tipo de dados). Por exemplo, um OBJECT que contenha informações sobre um tornado pode precisar de informações sobre a velocidade do vento em diferentes momentos durante o tornado, de modo que sua estrutura de dados pode se parecer com a seguinte:

  1. O nível superior é um ARRAY.

  2. Cada célula desse ARRAY contém um OBJECT que descreve um tornado.

  3. Cada OBJECT contém um ARRAY de dados da velocidade do vento.

  4. Cada célula desse ARRAY interno é um OBJECT que contém dados com chaves como, por exemplo:

    • Carimbo de data/hora da velocidade do vento.

    • Local da velocidade do vento.

    • A velocidade do vento em KPH (quilômetros por hora).

    Em alguns casos, os dados podem estar incompletos. Por exemplo, se a velocidade do vento em um determinado local foi estimada com base nos danos visíveis após o tornado (em vez de ser medida diretamente durante o tornado), então os dados podem incluir o local e a velocidade do vento, mas não um carimbo de data/hora.

Carregamento de dados semiestruturados

O Snowflake pode importar dados semiestruturados dos formatos JSON, Avro, ORC, Parquet e XML, e armazená-los nos tipos de dados Tipos de dados do Snowflake projetados especificamente para aceitar dados semiestruturados.

Dependendo da estrutura dos dados, do tamanho dos dados e da forma como o usuário escolhe importar os dados, os dados semiestruturados podem ser armazenados em uma única coluna ou divididos em várias colunas.

Os passos para o carregamento de dados semiestruturados em tabelas são similares aos passos para carregamento de dados estruturados em tabelas. Entretanto, ao carregar e armazenar dados semiestruturados, você também pode especificar explicitamente todos, alguns ou nenhum dos dados da estrutura:

  • Se os seus dados forem um conjunto de pares chave-valor, você pode carregá-los em uma coluna do tipo OBJECT.

  • Se os seus dados forem uma matriz, você pode carregá-los em uma coluna do tipo ARRAY.

  • Se você tiver O que são dados hierárquicos?, você pode escolher uma das seguintes opções:

    • Dividir os dados em várias colunas. Você pode:

      • Extrair e transformar explicitamente as colunas de dados semiestruturados em colunas separadas nas tabelas de destino.

      • Usar o Snowflake para detectar e recuperar automaticamente as definições das colunas dos arquivos preparados de dados semiestruturados. Criar tabelas, tabelas externas, ou exibições do Snowflake a partir das definições das colunas. Para economizar tempo, crie tabelas com definições de coluna recuperadas automaticamente dos arquivos preparados.

        Nota

        • Esse recurso de detecção e recuperação oferece suporte aos arquivos Apache Parquet, Apache Avro, ORC, JSON e CSV. O suporte para arquivos CSV e JSON está atualmente em versão preliminar.

    • Armazenar os dados em uma única coluna do tipo VARIANT. Você pode:

      • Especificar explicitamente a estrutura (por exemplo, especificar uma hierarquia de tipos de dados VARIANT, ARRAY e OBJECT).

      • Carregar os dados sem especificar explicitamente a estrutura. Se você especificar um formato de dados que o Snowflake reconhece e analisa (JSON, Avro, Parquet ou ORC), os dados serão convertidos para um formato de dados interno que usa os tipos de dados VARIANT, ARRAY e OBJECT do Snowflake.

Se os dados forem complexos ou se um valor individual exigir mais do que cerca de 16MB de espaço de armazenamento, então você pode usar mais de uma das técnicas anteriores. Por exemplo, você pode dividir os dados em várias colunas, e algumas dessas colunas podem conter uma hierarquia de tipos de dados especificada explicitamente.

Você pode carregar dados semiestruturados das seguintes maneiras:

  • Especifique o formato dos dados de entrada e o tipo de dados do Snowflake ao criar a tabela e carregar os dados. Por exemplo, no código abaixo, o tipo de dados VARIANT é especificado na instrução CREATE TABLE, enquanto o formato de dados de entrada JSON é especificado na cláusula TYPE = <formato_dados> do comando COPY INTO <tabela>:

    CREATE TABLE my_table (my_variant_column VARIANT);
    COPY INTO my_table ... FILE FORMAT = (TYPE = 'JSON') ...
    
    Copy
  • Especifique o formato dos dados de entrada e o tipo de dados do Snowflake chamando uma função apropriada para converter os dados. Por exemplo, para converter dados formatados em JSON para um valor VARIANT, chame PARSE_JSON, como mostrado abaixo:

    INSERT INTO my_table (my_variant_column) SELECT PARSE_JSON('{...}');
    
    Copy

Quando os dados são armazenados em tipos de dados ARRAY, OBJECT ou VARIANT, ou em uma hierarquia desses tipos, você pode consultá-los.

Armazenamento de dados semiestruturados

Os dados semiestruturados são tipicamente armazenados nos seguintes tipos de dados do Snowflake:

  • ARRAY: semelhante a uma matriz em outras linguagens.

  • OBJECT: semelhante a um objeto JSON, também chamado de “dicionário”, “hash” ou “mapa” em muitas linguagens. Contém pares chave-valor.

  • VARIANT: um tipo de dados que pode conter um valor de qualquer outro tipo de dados (incluindo ARRAY e OBJECT). VARIANT é usado para criar e armazenar dados hierárquicos.

(Se os dados importados estiverem divididos em várias colunas antes de serem armazenados, então algumas ou todas essas colunas podem ser tipos de dados simples, como FLOAT, VARCHAR, etc.)

Os tipos de dados ARRAY, OBJECT e VARIANT podem ser usados individualmente, ou aninhados para criar uma hierarquia.

Se os dados forem importados no formato JSON, Avro, ORC ou Parquet, então o Snowflake poderá criar a hierarquia para você e armazená-la em um VARIANT. Você também pode criar uma hierarquia manualmente.

Independentemente de como a hierarquia tenha sido criada, o Snowflake converte os dados para um formato otimizado de armazenamento interno que usa ARRAY, OBJECT e VARIANT. Esse formato de armazenamento interno oferece suporte a consultas SQL rápidas e eficientes.

Para obter mais informações sobre os tipos de dados ARRAY, OBJECT e VARIANT, consulte Tipos de dados semiestruturados.

Consulta de dados semiestruturados

O Snowflake oferece suporte a operadores para:

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

Para obter mais informações sobre como consultar dados XML especificando tags XML, consulte a documentação da função XMLGET.