DBMS_CLOUD Tipos Complexos de Pacote Avro, ORC e Parquet

Descreve o mapeamento dos tipos complexos Avro, ORC e Parquet para os tipos de dados Oracle.

O Autonomous Database suporta tipos de dados complexos, incluindo os seguintes:

  • estrutura

  • listar

  • mapa

  • união

  • array

Quando você especifica um tipo de arquivo de origem Avro, ORC ou Parquet e o arquivo de origem inclui colunas complexas, as consultas do Autonomous Database retornam JSON para as colunas complexas. Isso simplifica o processamento dos resultados da consulta; você pode usar os recursos avançados de parsing de JSON da Oracle de forma consistente nos tipos de arquivo e de dados. A seguinte tabela mostra o formato dos tipos complexos no Autonomous Database:

Observação

Os campos complexos são mapeados para colunas VARCHAR2 e são aplicados limites de tamanho VARCHAR2.
Tipo Parquet ORC Avro da Oracle
Lista: sequência de valores Lista Lista Array VARCHAR2 ( formato JSON)
Map: lista de objetos com uma única chave Mapear Mapear Mapear VARCHAR2 ( formato JSON)
Union: valores de tipo diferente Não Disponível União União VARCHAR2 ( formato JSON)
Object: zero ou mais pares de chave/valor Estrutura Estrutura Gravar VARCHAR2 ( formato JSON)

Se seus arquivos de origem ORC, Parquet ou Avro contiverem tipos complexos, você poderá consultar a saída JSON para esses tipos complexos comuns. Por exemplo, a seguir é mostrado um arquivo ORC, movie-info.orc, com um tipo complexo (o mesmo tratamento de tipo complexo se aplica aos arquivos de origem Parquet e Avro).

Considere o arquivo movie-info.orc com o seguinte esquema:

id    int
original_title string
overview       string
poster_path    string
release_date   string
vote_count     int
runtime        int
popularity     double
genres         array<struct<id:int,name:string>

Observe que cada filme é categorizado por vários genres usando um array de genres. O array genres é um array de structs e cada item tem um id (int) e um name (string). O array genres é considerado um tipo complexo. Você pode criar uma tabela sobre esse arquivo ORC usando DBMS_CLOUD.CREATE_EXTERNAL_TABLE da seguinte forma:

BEGIN
DBMS_CLOUD.CREATE_EXTERNAL_TABLE(
        table_name =>'movie_info',
        credential_name =>'OBJ_STORE_CRED',
        file_uri_list =>'https://objectstorage.us-phoenix-1.oraclecloud.com/n/mytenancy/b/movies/o/movie-info.orc',
        format => '{"type":"orc", "schema": "first"}');
END;
/

Quando você cria a tabela externa, o banco de dados gera automaticamente as colunas com base no esquema do arquivo ORC (se você estiver usando Avro ou Parquet, o mesmo será aplicado). Para esse exemplo, DBMS_CLOUD.CREATE_EXTERNAL_TABLE cria uma tabela no seu banco de dados da seguinte forma:

CREATE TABLE "ADMIN"."MOVIE_INFO" 
    ( "ID"
      NUMBER(10,0), 
      "ORIGINAL_TITLE"  VARCHAR2(4000 BYTE) COLLATE "USING_NLS_COMP", 
      "OVERVIEW"        VARCHAR2(4000 BYTE) COLLATE "USING_NLS_COMP", 
      "POSTER_PATH"     VARCHAR2(4000 BYTE) COLLATE "USING_NLS_COMP", 
      "RELEASE_DATE"    VARCHAR2(4000 BYTE) COLLATE "USING_NLS_COMP", 
      "VOTE_COUNT"      NUMBER(10,0), 
      "RUNTIME"         NUMBER(10,0), 
      "POPULARITY"      BINARY_DOUBLE, 
      "GENRES"          VARCHAR2(4000 BYTE) COLLATE "USING_NLS_COMP"
    )  DEFAULT COLLATION "USING_NLS_COMP"
    ORGANIZATION EXTERNAL 
     ( TYPE      ORACLE_BIGDATA
       DEFAULT DIRECTORY "DATA_PUMP_DIR"
       ACCESS PARAMETERS
       ( com.oracle.bigdata.credential.name=OBJ_STORE_CRED
         com.oracle.bigdata.fileformat=ORC
   )
       LOCATION
        (
      'https://objectstorage.us-phoenix-1.oraclecloud.com/n/mytenancy/b/movies/o/movie-info.orc'
           )
     )
   REJECT LIMIT UNLIMITED 
   PARALLEL;
 )

Agora você pode consultar os dados do filme:

SELECT original_title, release_date, genres 
     FROM movie_info 
     WHERE release_date > '2000'
     ORDER BY original_title;

Isso produz a seguinte saída:


original_title              release_date   genres
(500) Days of Summer        2009           [{"id":3,"name":"Drama"},{"id":6,"name":"Comedy"},{"id":17,"name":"Horror"},{"id":19,"name":"Western"},{"id":18,"name":"War"},{"id":15,"name":"Romance"}]
10,000 BC                   2008           [{"id":6,"name":"Comedy"}]
11:14                       2003           [{"id":9,"name":"Thriller"},{"id":14,"name":"Family"}]
127 Hours                   2010           [{"id":6,"name":"Comedy"},{"id":3,"name":"Drama"}]
13 Going on 30              2004           [{"id":6,"name":"Comedy"},{"id":3,"name":"Drama"},{"id":18,"name":"War"},{"id":15,"name":"Romance"}]
1408                        2007           [{"id":45,"name":"Sci-Fi"},{"id":6,"name":"Comedy"},{"id":17,"name":"Horror"},{"id":6,"name":"Comedy"},{"id":18,"name":"War"}]

Observe que o tipo complexo genres é retornado como array JSON.

Para tornar os dados JSON mais úteis, você pode transformar a coluna usando funções JSON da Oracle. Por exemplo, você pode usar a notação JSON "." bem como as funções de transformação mais avançadas, como JSON_TABLE.

Consulte Acesso de Notificação por Pontos Simples a Dados JSON para obter informações sobre a notação.

Consulte Função SQL/JSON JSON_TABLE para obter informações sobre JSON_TABLE.

O exemplo a seguir mostra uma consulta na tabela que seleciona cada valor do array e transforma o valor em uma linha no conjunto de resultados:
SELECT original_title, release_date, m.genre_name, genres
    FROM movie_info mi,
       JSON_TABLE(mi.genres, '$.name[*]'
        COLUMNS (genre_name VARCHAR2(25) PATH
      '$')                 
                 ) AS m
 WHERE rownum < 10;

O JSON_TABLE cria uma linha para cada valor do array, considera a junção externa e a estrutura é analisada para extrair o nome do gênero. Isso produz a seguinte saída:


original_title                   release_date         genre_name        genres
(500) Days of Summer             2009                 Drama             [{"id":3,"name":"Drama"},{"id":6,"name":"Comedy"},
                                                                        {"id":17,"name":"Horror"},{"id":19,"name":"Western"},
                                                                        {"id":18,"name":"War"},{"id":15,"name":"Romance"}]
(500) Days of Summer             2009                 Comedy            [{"id":3,"name":"Drama"},{"id":6,"name":"Comedy"},
                                                                        {"id":17,"name":"Horror"},{"id":19,"name":"Western"},
                                                                        {"id":18,"name":"War"},{"id":15,"name":"Romance"}]
(500) Days of Summer             2009                 Horror            [{"id":3,"name":"Drama"},{"id":6,"name":"Comedy"},
                                                                        {"id":17,"name":"Horror"},{"id":19,"name":"Western"},
                                                                        {"id":18,"name":"War"},{"id":15,"name":"Romance"}]
(500) Days of Summer             2009                 Western           [{"id":3,"name":"Drama"},{"id":6,"name":"Comedy"},
                                                                        {"id":17,"name":"Horror"},{"id":19,"name":"Western"},
                                                                        {"id":18,"name":"War"},{"id":15,"name":"Romance"}]
(500) Days of Summer             2009                 War               [{"id":3,"name":"Drama"},{"id":6,"name":"Comedy"},
                                                                        {"id":17,"name":"Horror"},{"id":19,"name":"Western"},
                                                                        {"id":18,"name":"War"},{"id":15,"name":"Romance"}]
(500) Days of Summer             2009                 Romance           [{"id":3,"name":"Drama"},{"id":6,"name":"Comedy"},
                                                                        {"id":17,"name":"Horror"},{"id":19,"name":"Western"},
                                                                        {"id":18,"name":"War"},{"id":15,"name":"Romance"}]
10,000 BC                        2008                 Comedy            [{"id":6,"name":"Comedy"}]
11:14                            2003                 Family            [{"id":9,"name":"Thriller"},{"id":14,"name":"Family"}]
11:14                            2003                 Thriller          [{"id":9,"name":"Thriller"},{"id":14,"name":"Family"}]
127 Hours                        2010                 Comedy            [{"id":6,"name":"Comedy"},{"id":3,"name":"Drama"}]
127 Hours                        2010                 Drama             [{"id":6,"name":"Comedy"},{"id":3,"name":"Drama"}]
13 Going on 30                   2004                 Romance           [{"id":6,"name":"Comedy"},{"id":3,"name":"Drama"},
                                                                        {"id":18,"name":"War"},{"id":15,"name":"Romance"}]
13 Going on 30                   2004                 Comedy            [{"id":6,"name":"Comedy"},{"id":3,"name":"Drama"},
                                                                        {"id":18,"name":"War"},{"id":15,"name":"Romance"}]
13 Going on 30                   2004                 War               [{"id":6,"name":"Comedy"},{"id":3,"name":"Drama"},
                                                                        {"id":18,"name":"War"},{"id":15,"name":"Romance"}]
13 Going on 30                   2004                 Drama             [{"id":6,"name":"Comedy"},{"id":3,"name":"Drama"},
                                                                        {"id":18,"name":"War"},{"id":15,"name":"Romance"}]