Types complexes Avro, ORC et Parquet pour le package DBMS_CLOUD

Décrit la mise en correspondance des types de données complexes Avro, ORC et Parquet avec les types de données Oracle.

Autonomous Database prend en charge les types de données complexes, notamment les types complexes suivants :

  • struct

  • liste

  • mapper

  • union

  • tableau

Lorsque vous indiquez un type de fichier source Avro, ORC ou Parquet et que le fichier source inclut des colonnes complexes, les requêtes Autonomous Database renvoient le format JSON pour les colonnes complexes. Cela simplifie le traitement des résultats de requête. Vous pouvez utiliser les puissantes fonctionnalités d'analyse JSON d'Oracle de manière cohérente entre les types de fichier et les types de données. Le tableau suivant présente le format des types complexes dans Autonomous Database :

Remarque

Les champs complexes sont mis en correspondance avec les colonnes VARCHAR2 et les limites de taille VARCHAR2 s'appliquent.
Type Parquet ORC Avro Oracle
Liste : séquence de valeurs Liste Liste Tableau VARCHAR2 (format JSON)
Carte : liste des objets à clé unique Correspondance Correspondance Correspondance VARCHAR2 (format JSON)
Union : valeurs de différents types Non disponible Union Union VARCHAR2 (format JSON)
Objet : zéro ou plusieurs paires clé-valeur Struct Struct Enregistrement VARCHAR2 (format JSON)

Si vos fichiers source ORC, Parquet ou Avro contiennent des types complexes, vous pouvez interroger la sortie JSON pour ces types complexes courants. Par exemple, l'exemple suivant illustre un fichier ORC, movie-info.orc, avec un type complexe (la même gestion de type complexe s'applique aux fichiers source Parquet et Avro).

Examinez le fichier movie-info.orc avec le schéma suivant :

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>

Chaque film est classé par plusieurs éléments genres à l'aide d'un tableau de genres. Le tableau genres est un élément array de structs et chaque élément comporte un élément id (int) et un élément name (string). Le tableau genres est considéré comme un type complexe. Vous pouvez créer une table sur ce fichier ORC à l'aide de DBMS_CLOUD.CREATE_EXTERNAL_TABLE comme suit :

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;
/

Lorsque vous créez la table externe, la base de données génère automatiquement les colonnes en fonction du schéma dans le fichier ORC (si vous utilisez Avro ou Parquet, la même chose s'applique). Pour cet exemple, DBMS_CLOUD.CREATE_EXTERNAL_TABLE crée une table dans la base de données comme suit :

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;
 )

Vous pouvez maintenant interroger les données de film :

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

La sortie suivante est générée :


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

Le type complexe genres est renvoyé en tant que tableau JSON.

Pour rendre les données JSON plus utiles, vous pouvez transformer la colonne à l'aide des fonctions JSON d'Oracle. Par exemple, vous pouvez utiliser la notation "." JSON ainsi que les fonctions de transformation les plus puissantes telles que JSON_TABLE.

Pour plus d'informations sur la notation ".", reportez-vous à Accès par points simple aux données JSON.

Pour plus d'informations sur JSON_TABLE, reportez-vous à Fonction SQL/JSON JSON_TABLE.

L'exemple suivant illustre une requête sur la table qui prend chaque valeur du tableau et transforme la valeur en ligne dans l'ensemble de résultats :
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;

JSON_TABLE crée une ligne pour chaque valeur du tableau, pense à la jointure externe et la structure est analysée pour extraire le nom du genre. La sortie suivante est générée :


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