Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.
Didacticiel : Faire une requête de données imbriquées avec Amazon Redshift Spectrum
Ce didacticiel explique comment interroger des données imbriquées avec Redshift Spectrum. Les données imbriquées sont des données qui contiennent des champs imbriqués. Les champs imbriqués sont des champs assemblés en une seule entité, tels que des tableaux, des structures ou des objets.
Rubriques
- Présentation
- Étape 1 : Création d’un tableau externe contenant des données imbriquées
- Étape 2 : interrogez vos données imbriquées dans Amazon S3 avec des extensions SQL
- Cas d’utilisation de données imbriquées
- Limitations des données imbriquées (version préliminaire)
- Sérialisation d'un complexe imbriqué JSON
Présentation
Amazon Redshift Spectrum prend en charge l'interrogation de données imbriquées dans les formats de fichier ParquetORC,JSON, et Ion. Redshift Spectrum accède aux données à l’aide de tableaux externes. Vous pouvez créer des tableaux externes qui utilisent les types de données complexes struct
, array
, et map
.
Par exemple, supposons que votre fichier de données contienne les données suivantes dans Amazon S3 dans un fichier nommé customers
. Bien qu'il n'y ait pas un seul élément racine, chaque JSON objet de cet exemple de données représente une ligne dans un tableau.
{"id": 1, "name": {"given": "John", "family": "Smith"}, "phones": ["123-457789"], "orders": [{"shipdate": "2018-03-01T11:59:59.000Z", "price": 100.50}, {"shipdate": "2018-03-01T09:10:00.000Z", "price": 99.12}] } {"id": 2, "name": {"given": "Jenny", "family": "Doe"}, "phones": ["858-8675309", "415-9876543"], "orders": [] } {"id": 3, "name": {"given": "Andy", "family": "Jones"}, "phones": [], "orders": [{"shipdate": "2018-03-02T08:02:15.000Z", "price": 13.50}] }
Vous pouvez utiliser Amazon Redshift Spectrum pour soumettre une requête sur les données imbriquées dans des fichiers. Le didacticiel suivant vous montre comment effectuer cette opération avec les données Apache Parquet.
Prérequis
Si vous n’utilisez pas encore Redshift Spectrum, suivez les étapes détaillées dans Mise en route avec Amazon Redshift Spectrum avant de poursuivre.
Pour créer un schéma externe, remplacez le IAM rôle ARN dans la commande suivante par le rôle ARN que vous avez créé dans Créer un IAM rôle. Exécutez ensuite la commande dans votre SQL client.
create external schema spectrum from data catalog database 'myspectrum_db' iam_role 'arn:aws:iam::123456789012:role/myspectrum_role' create external database if not exists;
Étape 1 : Création d’un tableau externe contenant des données imbriquées
Vous pouvez afficher les données source
Exécutez la commande suivante pour créer un tableau externe pour ce didacticiel.
CREATE EXTERNAL TABLE spectrum.customers ( id int, name struct<given:varchar(20), family:varchar(20)>, phones array<varchar(20)>, orders array<struct<shipdate:timestamp, price:double precision>> ) STORED AS PARQUET LOCATION 's3://redshift-downloads/tickit/spectrum/customers/';
Dans l’exemple précédent, le tableau externe spectrum.customers
utilise les types de données struct
et array
pour définir les colonnes dotées de données imbriquées. Amazon Redshift Spectrum prend en charge l'interrogation de données imbriquées dans les formats de fichier ParquetORC,JSON, et Ion. Le paramètre STORED AS
est PARQUET
pour les fichiers Apache Parquet. Le paramètre LOCATION
doit se référer au dossier Amazon S3 contenant les données ou fichiers imbriqués. Pour de plus amples informations, veuillez consulter CREATE EXTERNAL TABLE.
Vous pouvez imbriquer les types array
et struct
à n’importe quel niveau. Vous pouvez par exemple définir une colonne nommée toparray
, comme l’illustre l’exemple suivant.
toparray array<struct<nestedarray: array<struct<morenestedarray: array<string>>>>>
Vous pouvez également imbriquer les types struct
comme l’illustre la colonne x
dans l’exemple suivant.
x struct<a: string, b: struct<c: integer, d: struct<e: string> > >
Étape 2 : interrogez vos données imbriquées dans Amazon S3 avec des extensions SQL
Redshift Spectrum prend en charge les requêtes et array
les map
types struct
complexes grâce à des extensions de la syntaxe Amazon Redshift. SQL
Extension 1 : Accès aux colonnes de structs
Vous pouvez extraire des données à partir des colonnes struct
à l’aide d’une notation par points qui connecte les noms de champs en chemins. Par exemple, la requête suivante retourne les noms et prénoms de clients. Le prénom est obtenu via le long chemin c.name.given
. Le nom de famille est obtenu via le long chemin c.name.family
.
SELECT c.id, c.name.given, c.name.family FROM spectrum.customers c;
La requête précédente renvoie les données suivantes.
id | given | family ---|-------|------- 1 | John | Smith 2 | Jenny | Doe 3 | Andy | Jones (3 rows)
Un struct
peut être une colonne d’un autre struct
, qui peut être une colonne d’un autre struct
et ce à tout niveau. Les chemins qui accèdent aux colonnes dans des struct
aussi profondément imbriqués peuvent être très longs. Par exemple, regardez la définition pour la colonne x
dans l’illustration suivante.
x struct<a: string, b: struct<c: integer, d: struct<e: string> > >
Vous pouvez accéder aux données dans e
en tant que x.b.d.e
.
Extension 2 : Répartition des tableaux dans une clause FROM
Vous pouvez extraire des données de colonnes array
(et, par extension, des colonnes map
) en précisant les colonnes array
dans une clause FROM
à la place des noms de tableaux. L’extension s’applique à la clause FROM
de la requête principale, ainsi qu’aux clauses FROM
des sous-requêtes.
Vous pouvez référencer les éléments array
d’après leur position, comme c.orders[0]
(version préliminaire).
En combinant le surplombage de arrays
avec des raccords, vous pouvez réaliser différentes sortes de désimbrication, comme les cas d’utilisation suivants l’expliquent.
Désimbrication à l’aide de raccords internes
La requête suivante sélectionne les dates d'expédition IDs des clients et des commandes pour les clients qui ont des commandes. L'SQLextension de la FROM clause c.orders
o
dépend de l'aliasc
.
SELECT c.id, o.shipdate FROM spectrum.customers c, c.orders o
Pour chaque c
de client disposant de commandes, la clause FROM
renvoie une ligne pour chaque commande o
du client c
. Cette ligne combine la ligne du client c
et la ligne de commande o
. Ensuite, la clause SELECT
garde uniquement le c.id
et le o.shipdate
. Le résultat est le suivant.
id| shipdate --|---------------------- 1 |2018-03-01 11:59:59 1 |2018-03-01 09:10:00 3 |2018-03-02 08:02:15 (3 rows)
L’alias c
fournit un accès aux champs du client et l’alias o
fournit un accès aux champs de commande.
La sémantique est similaire à celle de la norme. SQL Vous pouvez envisager la clause FROM
comme exécutant la boucle imbriquée suivante qui est suivie par la sélection de champs pour la sortie par SELECT
.
for each customer c in spectrum.customers for each order o in c.orders output c.id and o.shipdate
Ainsi, si un client ne dispose pas de commande, le client n’apparaît pas dans le résultat.
Vous pouvez également envisager ceci comme une clause FROM
qui exécute un JOIN
avec le tableau customers
et le pan orders
. Dans les faits, vous pouvez également rédiger la requête comme l’illustre l’exemple suivant.
SELECT c.id, o.shipdate FROM spectrum.customers c INNER JOIN c.orders o ON true
Note
Si un schéma nommé c
existe avec un tableau nommé orders
, alors c.orders
se réfère au tableau orders
, et non à la colonne de pan customers
.
Désimbrication à l’aide de raccords gauches
La requête suivante sort tous les noms des clients et leurs commandes. Si un client n’a pas encore placé de commande, son nom sera tout de même renvoyé. Toutefois, dans ce cas, les colonnes de commande sont les suivantesNULL, comme indiqué dans l'exemple suivant pour Jenny Doe.
SELECT c.id, c.name.given, c.name.family, o.shipdate, o.price FROM spectrum.customers c LEFT JOIN c.orders o ON true
La requête précédente renvoie les données suivantes.
id | given | family | shipdate | price ----|---------|---------|----------------------|-------- 1 | John | Smith | 2018-03-01 11:59:59 | 100.5 1 | John | Smith | 2018-03-01 09:10:00 | 99.12 2 | Jenny | Doe | | 3 | Andy | Jones | 2018-03-02 08:02:15 | 13.5 (4 rows)
Extension 3 : Obtenir directement à un pan de scalaires en utilisant un alias
Lorsqu’un alias p
dans une clause FROM
surplombe tout un tableau de scalaires, la requête se réfère aux valeurs de p
en tant que p
. Par exemple, la requête suivante produit des paires de noms de clients et de numéros de téléphone.
SELECT c.name.given, c.name.family, p AS phone FROM spectrum.customers c LEFT JOIN c.phones p ON true
La requête précédente renvoie les données suivantes.
given | family | phone -------|----------|----------- John | Smith | 123-4577891 Jenny | Doe | 858-8675309 Jenny | Doe | 415-9876543 Andy | Jones | (4 rows)
Extension 4 : Accès aux éléments de cartes
Redshift Spectrum traite le type de donnée map
comme un type de array
contenant des types struct
avec une colonne key
et une colonne value
. La key
doit être scalar
; la valeur peut être de n’importe quel type de donnée.
Par exemple, le code suivant crée un tableau externe avec une map
pour stocker les numéros de téléphone.
CREATE EXTERNAL TABLE spectrum.customers2 ( id int, name struct<given:varchar(20), family:varchar(20)>, phones map<varchar(20), varchar(20)>, orders array<struct<shipdate:timestamp, price:double precision>> ) STORED AS PARQUET LOCATION 's3://redshift-downloads/tickit/spectrum/customers/';
Parce qu’un type de map
se comporte comme un type de array
avec des colonnes key
et value
, vous pouvez penser aux schémas précédents comme s’ils étaient les suivants.
CREATE EXTERNAL TABLE spectrum.customers3 ( id int, name struct<given:varchar(20), family:varchar(20)>, phones array<struct<key:varchar(20), value:varchar(20)>>, orders array<struct<shipdate:timestamp, price:double precision>> ) STORED AS PARQUET LOCATION 's3://redshift-downloads/tickit/spectrum/customers/';
La requête suivante renvoie les noms de clients avec un numéro de téléphone mobile et renvoie le numéro pour chaque nom. La requête de carte est traitée comme l’équivalent d’une requête de array
imbriquée de types struct
. La requête suivante ne renvoie des données que si vous avez créé le tableau externe précédemment évoqué.
SELECT c.name.given, c.name.family, p.value
FROM spectrum.customers c, c.phones p
WHERE p.key = 'mobile';
Note
Le key
for a map
correspond à Ion et string
aux types de JSON fichiers.