Types de données semi-structurées¶
Les types de données Snowflake suivants peuvent contenir d’autres types de données :
VARIANT (peut contenir une valeur de tout autre type de données).
OBJECT (peut contenir directement une valeur VARIANT et donc contenir indirectement une valeur de tout autre type de données, y compris elle-même).
ARRAY (peut contenir directement une valeur VARIANT et donc contenir indirectement une valeur de tout autre type de données, y compris elle-même).
Nous faisons souvent référence à ces types de données comme étant des types de données semi-structurées. À proprement parler, OBJECT est le seul de ces types de données qui, à lui seul, possède toutes les caractéristiques d’un véritable type de données semi-structurées. Toutefois, la combinaison de ces types de données permet de représenter de façon explicite des structures de données hiérarchiques arbitraires, qui peuvent être utilisées pour charger et exploiter des données dans des formats semi-structurées (par exemple JSON, Avro, ORC, Parquet ou XML).
Note
Pour plus d’informations sur les types de données structurés (par exemple, ARRAY(INTEGER), OBJECT(ville VARCHAR), ou MAP(VARCHAR, VARCHAR), voir Types de données structurés.
Chacun de ces types de données est décrit dans cette rubrique.
VARIANT¶
Une valeur VARIANT peut stocker une valeur de tout autre type, y compris des valeurs OBJECT et ARRAY.
Caractéristiques d’une valeur VARIANT¶
Une valeur VARIANT peut avoir une taille maximale de 16 MB de données non compressées. Toutefois, dans la pratique, la taille maximale est généralement inférieure en raison d’une surcharge interne. La taille maximale dépend également de l’objet stocké.
Insertion de données VARIANT¶
Pour insérer directement des données VARIANT, utilisez INSERT INTO ... SELECT
. L’exemple suivant montre comment insérer des données au format JSON dans une valeur VARIANT :
CREATE OR REPLACE TABLE variant_insert (v VARIANT);
INSERT INTO variant_insert (v)
SELECT PARSE_JSON('{"key3": "value3", "key4": "value4"}');
SELECT * FROM variant_insert;
+---------------------+
| V |
|---------------------|
| { |
| "key3": "value3", |
| "key4": "value4" |
| } |
+---------------------+
En utilisant des valeurs VARIANT¶
Pour convertir une valeur à partir du type de données VARIANT ou vers celui-ci, vous pouvez explicitement utiliser la fonction CAST , la fonction TO_VARIANT ou l’opérateur ::
(par exemple, expression::VARIANT
).
Dans certaines situations, une valeur peut être implicitement convertie en valeur VARIANT. Pour plus de détails, voir Conversion de type de données.
L’exemple de code ci-dessous montre comment utiliser une valeur VARIANT, notamment comment effectuer une conversion à partir d’une valeur VARIANT et vers une valeur VARIANT.
Créer une table et insérer une valeur :
CREATE OR REPLACE TABLE varia (float1 FLOAT, v VARIANT, float2 FLOAT);
INSERT INTO varia (float1, v, float2) VALUES (1.23, NULL, NULL);
Le premier UPDATE convertit une valeur à partir d’une valeur FLOAT en valeur VARIANT. La deuxième UPDATE convertit une valeur VARIANT en valeur FLOAT.
UPDATE varia SET v = TO_VARIANT(float1); -- converts from a FLOAT value to a VARIANT value.
UPDATE varia SET float2 = v::FLOAT; -- converts from a VARIANT value to a FLOAT value.
SELECT toutes les valeurs :
SELECT * FROM varia;
+--------+-----------------------+--------+
| FLOAT1 | V | FLOAT2 |
|--------+-----------------------+--------|
| 1.23 | 1.230000000000000e+00 | 1.23 |
+--------+-----------------------+--------+
Comme indiqué dans l’exemple précédent, pour convertir une valeur du type de données VARIANT, convertissez la valeur VARIANT dans le type de données cible. Par exemple, l’instruction suivante utilise l’opérateur ::
pour convertir la VARIANT en FLOAT :
SELECT my_variant_column::FLOAT * 3.14 FROM ...;
Les données VARIANT stockent à la fois la valeur et le type de données de la valeur. Vous pouvez ainsi utiliser des valeurs VARIANT dans des expressions où le type de données de la valeur est valide sans avoir à effectuer une conversion préalable de VARIANT. Par exemple, si la colonne VARIANT my_variant_column
contient une valeur numérique, vous pouvez directement multiplier my_variant_column
par une autre valeur numérique :
SELECT my_variant_column * 3.14 FROM ...;
Vous pouvez récupérer le type de données natif de la valeur en utilisant la fonction TYPEOF.
Par défaut, lorsque des valeurs VARCHAR, DATE, TIME et TIMESTAMP sont extraites d’une colonne VARIANT, les valeurs sont entourées de guillemets doubles. Vous pouvez éliminer les guillemets en convertissant explicitement les valeurs en types de données sous-jacents (par exemple, de VARIANT à VARCHAR). Par exemple :
SELECT 'Sample', 'Sample'::VARIANT, 'Sample'::VARIANT::VARCHAR;
+----------+-------------------+----------------------------+
| 'SAMPLE' | 'SAMPLE'::VARIANT | 'SAMPLE'::VARIANT::VARCHAR |
|----------+-------------------+----------------------------|
| Sample | "Sample" | Sample |
+----------+-------------------+----------------------------+
Une valeur VARIANT peut être manquante (contenir SQL NULL), ce qui est différent d’une valeur VARIANT null, qui est une valeur réelle utilisée pour représenter une valeur nulle dans les données semi-structurées. VARIANT null est une valeur true qui se compare à elle-même. Pour plus d’informations, voir VARIANT null.
Si les données ont été chargées à partir du format JSON et stockées dans la colonne VARIANT, alors les considérations suivantes s’appliquent :
Pour les données qui sont le plus souvent régulières et n’utilisent que des types JSON natifs (comme les chaînes et les nombres), la performance est très similaire pour le stockage et les opérations de requête sur les données relationnelles et les données dans une colonne VARIANT.
Pour les données non natives (telles que les dates et les horodatages), les valeurs sont stockées sous forme de chaînes lorsqu’elles sont chargées dans une colonne VARIANT. Les opérations sur ces valeurs peuvent donc être plus lentes et consommer plus d’espace que lorsqu’elles sont stockées dans une colonne relationnelle avec le type de données correspondant.
Pour plus d’informations sur l’utilisation du type de données VARIANT, voir Considérations pour les données semi-structurées stockées dans des VARIANT.
Pour plus d’informations sur l’interrogation de données semi-structurées stockées dans une colonne VARIANT, voir Interrogation de données semi-structurées.
Utilisations courantes des données VARIANT¶
Les données VARIANT sont généralement utilisées lorsque :
Vous voulez créer des données hiérarchiques en définissant explicitement une hiérarchie qui contient au moins deux ARRAYs ou OBJECTs.
Vous voulez charger directement des données JSON, Avro, ORC ou Parquet, sans décrire explicitement la structure hiérarchique des données.
Snowflake peut convertir des données qui sont aux formats JSON, Avro, ORC ou Parquet en une hiérarchie interne de données ARRAY, OBJECT et VARIANT et stocker ces données hiérarchiques directement dans une valeur VARIANT. Bien que vous puissiez construire manuellement la hiérarchie de données vous-même, il est généralement plus facile de laisser Snowflake le faire pour vous.
Pour plus d’informations sur le chargement et la conversion de données semi-structurées, voir Chargement de données semi-structurées.
OBJECT¶
Une valeur OBJECT Snowflake est analogue à un « objet JSON ». Dans d’autres langages de programmation, le type de données correspondant est souvent appelé « dictionnaire », « hachage » ou « map ».
Une valeur OBJECT contient des paires clé-valeur.
Caractéristiques d’une valeur OBJECT¶
Dans des données OBJECT semi-structurées Snowflake, chaque clé est un VARCHAR et chaque valeur est une valeur VARIANT.
Comme une valeur VARIANT peut stocker une valeur dans tout autre type de données, différentes valeurs VARIANT (dans différentes paires clé-valeur) peuvent avoir différents types de données sous-jacentes. Par exemple, une valeur OBJECT peut contenir le nom d’une personne sous forme de valeur VARCHAR et son âge sous forme de valeur INTEGER. Dans l’exemple ci-dessous, le nom et l’âge sont convertis en valeurs VARIANT.
SELECT OBJECT_CONSTRUCT(
'name', 'Jones'::VARIANT,
'age', 42::VARIANT);
Les considérations suivantes s’appliquent aux données OBJECT :
Actuellement, Snowflake ne prend pas en charge les objets explicitement typés.
Dans une paire clé-valeur, la clé ne doit pas être une chaîne vide. De plus, ni la clé ni la valeur ne doivent être NULL.
La longueur maximale d’une valeur OBJECT est de 16 MB.
Une valeur OBJECT peut contenir des données semi-structurées.
Une valeur OBJECT peut être utilisée pour créer des structures de données hiérarchiques.
Note
Snowflake prend également en charge le type de données OBJECT structurées , qui autorise des valeurs autres que les valeurs VARIANT. Un type d’OBJECT structuré définit également les clés qui doivent être présentes dans une valeur OBJECT de ce type. Pour plus d’informations, voir Types de données structurés.
Insertion de données OBJECT¶
Pour insérer directement des données OBJECT, utilisez INSERT INTO ... SELECT
.
L’exemple suivant utilise la fonction OBJECT_CONSTRUCT pour construire la valeur OBJECT qu’il insère.
CREATE OR REPLACE TABLE object_example (object_column OBJECT);
INSERT INTO object_example (object_column)
SELECT OBJECT_CONSTRUCT('thirteen', 13::VARIANT, 'zero', 0::VARIANT);
SELECT * FROM object_example;
+-------------------+
| OBJECT_COLUMN |
|-------------------|
| { |
| "thirteen": 13, |
| "zero": 0 |
| } |
+-------------------+
Dans chaque paire clé-valeur, la valeur a été explicitement convertie en VARIANT. La conversion explicite n’était pas nécessaire dans ces cas. Snowflake peut implicitement faire des conversions en VARIANT. (Pour des informations sur la conversion implicite, voir Conversion de type de données).
Vous pouvez également utiliser une constante OBJECT pour spécifier la valeur OBJECT à insérer. Pour plus d’informations, voir Constantes OBJECT.
Constantes OBJECT¶
Une constante (également appelée littéral) fait référence à une valeur de données fixe. Snowflake prend en charge l’utilisation de constantes pour spécifier des valeurs OBJECT. Les constantes OBJECT sont délimitées par des accolades ({
et }
).
Les constantes OBJECT ont la syntaxe suivante :
{ [<key>: <value> [, <key>: <value> , ...]] }
Où :
key
Clé dans une paire clé-valeur. La
key
doit être une chaîne littérale.value
Valeur associée à la clé. La
value
peut être un littéral ou une expression. Lavalue
peut être n’importe quel type de données.
Voici quelques exemples qui spécifient des constantes OBJECT :
{}
est une valeur OBJECT vide.{ 'key1': 'value1' , 'key2': 'value2' }
contient les paires clé-valeur spécifiées pour la valeur OBJECT en utilisant des littéraux pour les valeurs.{ 'key1': c1+1 , 'key2': c1+2 }
contient les paires clé-valeur spécifiées pour la valeur OBJECT en utilisant des expressions pour les valeurs.
{*}
est un caractère générique qui construit la valeur OBJECT à partir des données spécifiées en utilisant les noms d’attributs comme clés et les valeurs associées comme valeurs.Lorsqu’il est spécifié dans une constante d’objet, le caractère générique peut être non qualifié ou qualifié avec un nom de table ou un alias. Par exemple, ces deux spécifications génériques sont valides :
SELECT {*} FROM my_table; SELECT {my_table1.*} FROM my_table1 INNER JOIN my_table2 ON my_table2.col1 = my_table1.col1;
Vous pouvez utiliser les mots-clés ILIKE et EXCLUDE dans une constante d’objet. Pour sélectionner des colonnes spécifiques, utilisez le mot-clé ILIKE. Par exemple, la requête suivante sélectionne les colonnes qui correspondent au modèle
col1%
dans le tableaumy_table
:SELECT {* ILIKE 'col1%'} FROM my_table;
Pour exclure des colonnes spécifiques, utilisez le mot-clé EXCLUDE. Par exemple, la requête suivante exclut
col1
dans le tableaumy_table
:SELECT {* EXCLUDE col1} FROM my_table;
La requête suivante exclut
col1
etcol2
dans la tablemy_table
:SELECT {* EXCLUDE (col1, col2)} FROM my_table;
Les caractères génériques ne peuvent pas être mélangés avec des paires clé-valeur. Par exemple, le caractère générique suivant n’est pas autorisé :
SELECT {*, 'k': 'v'} FROM my_table;
Plusieurs caractères génériques ne peuvent pas être utilisés dans une constante d’objet. Par exemple, le caractère générique suivant n’est pas autorisé :
SELECT {t1.*, t2.*} FROM t1, t2;
Les instructions suivantes utilisent une constante OBJECT et la fonction OBJECT_CONSTRUCT pour effectuer une insertion de données OBJECT dans une table. Les valeurs OBJECT contiennent les noms et les capitales de deux provinces canadiennes.
CREATE OR REPLACE TABLE my_object_table (my_object OBJECT);
INSERT INTO my_object_table (my_object)
SELECT { 'PROVINCE': 'Alberta'::VARIANT , 'CAPITAL': 'Edmonton'::VARIANT };
INSERT INTO my_object_table (my_object)
SELECT OBJECT_CONSTRUCT('PROVINCE', 'Manitoba'::VARIANT , 'CAPITAL', 'Winnipeg'::VARIANT );
SELECT * FROM my_object_table;
+--------------------------+
| MY_OBJECT |
|--------------------------|
| { |
| "CAPITAL": "Edmonton", |
| "PROVINCE": "Alberta" |
| } |
| { |
| "CAPITAL": "Winnipeg", |
| "PROVINCE": "Manitoba" |
| } |
+--------------------------+
L’exemple suivant utilise un caractère générique ({*}
) pour insérer des données OBJECT en obtenant les noms et les valeurs des attributs à partir de la clause FROM. Tout d’abord, créez une table nommée demo_ca_provinces
avec des valeurs VARCHAR qui contiennent les noms des provinces et des capitales :
CREATE OR REPLACE TABLE demo_ca_provinces (province VARCHAR, capital VARCHAR);
INSERT INTO demo_ca_provinces (province, capital) VALUES
('Ontario', 'Toronto'),
('British Columbia', 'Victoria');
SELECT province, capital
FROM demo_ca_provinces
ORDER BY province;
+------------------+----------+
| PROVINCE | CAPITAL |
|------------------+----------|
| British Columbia | Victoria |
| Ontario | Toronto |
+------------------+----------+
Insérez des données d’objet dans la my_object_table
en utilisant les données de la table demo_ca_provinces
:
INSERT INTO my_object_table (my_object)
SELECT {*} FROM demo_ca_provinces;
SELECT * FROM my_object_table;
+----------------------------------+
| MY_OBJECT |
|----------------------------------|
| { |
| "CAPITAL": "Edmonton", |
| "PROVINCE": "Alberta" |
| } |
| { |
| "CAPITAL": "Winnipeg", |
| "PROVINCE": "Manitoba" |
| } |
| { |
| "CAPITAL": "Toronto", |
| "PROVINCE": "Ontario" |
| } |
| { |
| "CAPITAL": "Victoria", |
| "PROVINCE": "British Columbia" |
| } |
+----------------------------------+
L’exemple suivant utilise des expressions pour les valeurs dans une constante OBJECT :
SET my_variable = 10;
SELECT {'key1': $my_variable+1, 'key2': $my_variable+2};
+--------------------------------------------------+
| {'KEY1': $MY_VARIABLE+1, 'KEY2': $MY_VARIABLE+2} |
|--------------------------------------------------|
| { |
| "key1": 11, |
| "key2": 12 |
| } |
+--------------------------------------------------+
Les instructions SQL spécifient les littéraux de chaîne à l’intérieur d’une valeur OBJECT avec des guillemets simples (comme ailleurs dans SQL Snowflake), mais les littéraux de chaîne à l’intérieur d’une valeur OBJECT sont affichés avec des guillemets doubles :
SELECT { 'Manitoba': 'Winnipeg' } AS province_capital;
+--------------------------+
| PROVINCE_CAPITAL |
|--------------------------|
| { |
| "Manitoba": "Winnipeg" |
| } |
+--------------------------+
Accès aux éléments d’une valeur OBJECT par clé¶
Pour récupérer la valeur d’une valeur OBJECT, indiquez la clé entre crochets, comme indiqué ci-dessous :
SELECT my_variant_column['key1'] FROM my_table;
Vous pouvez également utiliser l’opérateur deux-points. La commande suivante montre que les résultats sont les mêmes, que vous utilisiez les crochets ou les deux-points :
SELECT object_column['thirteen'],
object_column:thirteen
FROM object_example;
+---------------------------+------------------------+
| OBJECT_COLUMN['THIRTEEN'] | OBJECT_COLUMN:THIRTEEN |
|---------------------------+------------------------|
| 13 | 13 |
+---------------------------+------------------------+
Pour plus d’informations sur l’opérateur deux-points, voir Notation par points, qui décrit l’utilisation des opérateurs :
et .
pour accéder à des données imbriquées.
Utilisations courantes des données OBJECT¶
Les données OBJECT sont généralement utilisées lorsqu’un ou plusieurs des éléments suivants sont vrais :
Vous avez plusieurs éléments de données qui sont identifiés par des chaînes. Par exemple, si vous souhaitez rechercher des informations par nom de province, vous pouvez utiliser une valeur OBJECT.
Vous voulez stocker des informations sur les données avec les données ; les noms (clés) ne sont pas simplement des identificateurs distincts, mais sont significatifs.
Les informations n’ont pas d’ordre naturel ou l’ordre peut être déduit uniquement à partir des clés.
La structure des données varie ou les données peuvent être incomplètes. Par exemple, si vous souhaitez créer un catalogue de livres contenant généralement le titre, le nom de l’auteur et la date de publication, mais que dans certains cas la date de publication est inconnue, vous pouvez utiliser une valeur OBJECT.
ARRAY¶
Un tableau Snowflake est similaire à un tableau dans de nombreux autres langages de programmation. Un tableau contient 0 ou plusieurs éléments de données. On accède à chaque élément en spécifiant sa position dans le tableau.
Caractéristiques d’un tableau¶
Chaque valeur d’un tableau semi-structuré est de type VARIANT. Une valeur VARIANT peut contenir une valeur de tout autre type de données.
Les valeurs d’autres types de données peuvent être converties en valeurs VARIANT, puis stockées dans un tableau. Certaines fonctions des tableaux, y compris ARRAY_CONSTRUCT, peuvent implicitement convertir des valeurs en valeurs VARIANT pour vous.
Comme les tableaux stockent des valeurs VARIANT et que les valeurs VARIANT peuvent contenir d’autres types de données, les types de données sous-jacents des valeurs d’un tableau ne doivent pas nécessairement être identiques. Toutefois, dans la plupart des cas, les éléments de données sont de types identiques ou compatibles, de sorte qu’ils peuvent tous être traités de la même manière.
Les considérations suivantes s’appliquent aux tableaux :
Snowflake ne prend pas en charge les tableaux d’éléments d’un type spécifique non-VARIANT.
Un tableau Snowflake est déclaré sans spécifier le nombre d’éléments. Un tableau peut croître dynamiquement en fonction d’opérations telles que ARRAY_APPEND. Snowflake ne prend actuellement pas en charge les tableaux de taille fixe.
Un tableau peut contenir des valeurs NULL.
La taille maximale théorique combinée de toutes les valeurs d’un tableau est 16 MB. Cependant, les tableaux ont une surcharge interne. La taille maximale concrète des données est généralement plus petite, en fonction du nombre et des valeurs des éléments.
Note
Snowflake prend également en charge les tableaux structurés, ce qui permet des éléments d’autres types que VARIANT. Pour plus d’informations, voir Types de données structurés.
Insertion de données ARRAY¶
Pour insérer directement des données ARRAY, utilisez INSERT INTO ... SELECT
.
Le code suivant utilise la fonction ARRAY_CONSTRUCT pour construire le tableau qu’il insère.
CREATE OR REPLACE TABLE array_example (array_column ARRAY);
INSERT INTO array_example (array_column)
SELECT ARRAY_CONSTRUCT(12, 'twelve', NULL);
Vous pouvez également utiliser une constante ARRAY pour spécifier le tableau à insérer. Pour plus d’informations, voir Constantes ARRAY.
Constantes ARRAY¶
Une constante (également appelée littéral) fait référence à une valeur de données fixe. Snowflake prend en charge l’utilisation de constantes pour spécifier des valeurs ARRAY. Les constantes ARRAY sont délimitées par des crochets ([
et ]
).
Les constantes ARRAY ont la syntaxe suivante :
[<value> [, <value> , ...]]
Où :
value
La valeur associée à un élément de tableau. La
value
peut être un littéral ou une expression. Lavalue
peut être n’importe quel type de données.
Voici quelques exemples qui spécifient des constantes ARRAY :
[]
est une valeur ARRAY vide.{ 'value1' , 'value2' }
contient les valeurs spécifiées pour la constante ARRAY utilisant des littéraux pour les valeurs.{ c1+1 , c1+2 }
contient les valeurs spécifiées pour la constante ARRAY utilisant des expressions pour les valeurs.
L’exemple suivant utilise une constante ARRAY pour spécifier le tableau à insérer.
INSERT INTO array_example (array_column)
SELECT [ 12, 'twelve', NULL ];
Les instructions suivantes utilisent une constante ARRAY et la fonction ARRAY_CONSTRUCT pour effectuer la même tâche :
UPDATE my_table SET my_array = [ 1, 2 ];
UPDATE my_table SET my_array = ARRAY_CONSTRUCT(1, 2);
L’exemple suivant utilise des expressions pour les valeurs dans une constante ARRAY :
SET my_variable = 10;
SELECT [$my_variable+1, $my_variable+2];
+----------------------------------+
| [$MY_VARIABLE+1, $MY_VARIABLE+2] |
|----------------------------------|
| [ |
| 11, |
| 12 |
| ] |
+----------------------------------+
Les instructions SQL spécifient les littéraux de chaîne à l’intérieur d’un tableau avec des guillemets simples (comme ailleurs dans SQL Snowflake), mais les littéraux de chaîne à l’intérieur d’un tableau sont affichés avec des guillemets doubles :
SELECT [ 'Alberta', 'Manitoba' ] AS province;
+--------------+
| PROVINCE |
|--------------|
| [ |
| "Alberta", |
| "Manitoba" |
| ] |
+--------------+
Accès aux éléments d’un tableau par indice ou par tranche¶
Les index des tableaux sont basés sur 0 ; le premier élément d’un tableau est donc l’élément 0.
On accède aux valeurs d’un tableau en spécifiant le numéro d’index d’un élément du tableau entre crochets. Par exemple, la requête suivante lit la valeur à la position d’index 2
dans le tableau stocké dans my_array_column
.
SELECT my_array_column[2] FROM my_table;
Les tableaux peuvent être imbriqués. La requête suivante lit l’élément zéro de l’élément zéro d’un tableau imbriqué :
SELECT my_array_column[0][0] FROM my_table;
Tenter d’accéder à un élément au-delà de la fin d’un tableau renvoie NULL.
Une tranche d’un tableau est une séquence d’éléments adjacents (c’est-à-dire un sous-ensemble contigu du tableau).
Vous pouvez accéder à une tranche d’un tableau en appelant la fonction ARRAY_SLICE. Par exemple :
SELECT ARRAY_SLICE(my_array_column, 5, 10) FROM my_table;
La fonction ARRAY_SLICE renvoie les éléments à partir de l’élément de départ spécifié (5 dans l’exemple ci-dessus) jusqu’à mais sans inclure l’élément final spécifié (10 dans l’exemple ci-dessus).
Un tableau vide ou une tranche vide est souvent indiqué par une paire de crochets sans rien entre eux ([]
).
Tableaux denses et clairsemés¶
Un tableau peut être dense ou clairsemé.
Dans un tableau dense, les valeurs d’index des éléments commencent à zéro et sont séquentielles (0, 1, 2, etc.). Cependant, dans un tableau clairsemé, les valeurs d’index peuvent être non séquentielles (par exemple, 0, 2, 5). Les valeurs ne doivent pas nécessairement commencer à 0.
Si un index n’a pas d’élément correspondant, alors la valeur correspondant à cet index est dite non définie. Par exemple, si un tableau clairsemé comporte trois éléments et que ces éléments sont aux index 0, 2 et 5, alors les éléments aux index 1, 3 et 4 sont undefined
.
0 2 5
+-----+.....+-------+.....+.....+------+
| Ann | | Carol | | | Fred |
+-----+.....+-------+.....+.....+------+
^ ^ ^
| | |
undefined--------------
Un élément indéfini est traité comme un élément. Par exemple, considérons l’exemple précédent d’un tableau clairsemé qui contient des éléments aux index 0, 2 et 5 (et n’a pas d’éléments après l’index 5). Si vous lisez la tranche contenant les éléments aux index 3 et 4, le résultat est similaire à ce qui suit :
[ undefined, undefined ]
La tentative d’accès à une tranche au-delà de la fin d’un tableau donne un tableau vide et non un tableau de valeurs undefined
. L’instruction SELECT suivante tente de lire au-delà du dernier élément du tableau clairsemé de l’échantillon :
SELECT ARRAY_SLICE(array_column, 6, 8) FROM table_1;
La sortie est un tableau vide :
+---------------------------------+
| array_slice(array_column, 6, 8) |
+---------------------------------+
| [ ] |
+---------------------------------+
Notez que undefined
est différent de NULL. Une valeur NULL dans un tableau est un élément défini.
Dans un tableau dense, chaque élément consomme de l’espace de stockage, même si la valeur de l’élément est NULL.
Dans un tableau clairsemé, les éléments undefined
ne consomment pas directement d’espace de stockage.
Dans un tableau dense, la plage théorique des valeurs d’index est comprise entre 0 et 16777215. (Le nombre maximum théorique d’éléments est 16777216, car la limite supérieure de la taille est de 16 MB (16777216 octets) et la plus petite valeur possible est un octet).
Dans un tableau clairsemé, la plage théorique des valeurs d’index est comprise entre 0 et 231 - 1. Cependant, en raison de la limitation de 16 MB, un tableau clairsemé ne peut pas contenir de valeurs 231. Le nombre maximal théorique de valeurs est toujours limité à 16777216.
(Rappelez-vous qu’en raison de la surcharge interne, la limite de taille pratique dans les tableaux denses et clairsemés est au moins légèrement inférieure au maximum théorique de 16 MB).
Vous pouvez créer un tableau clairsemé en utilisant la fonction ARRAY_INSERT pour insérer des valeurs à des points d’index spécifiques dans un tableau (en laissant les autres éléments du tableau undefined
). Notez que parce que ARRAY_INSERT pousse les éléments vers la droite, ce qui modifie les valeurs d’index requises pour y accéder, vous souhaitez presque toujours remplir un tableau clairsemé de gauche à droite (c’est-à-dire de 0 vers le haut, en augmentant la valeur de l’index pour chaque nouvelle valeur insérée).
Utilisations courantes des données ARRAY¶
Les données ARRAY sont généralement utilisées lorsqu’un ou plusieurs des éléments suivants sont vrais :
Il existe un ensemble de données, et chaque élément de l’ensemble est structuré de la même manière ou de manière similaire.
Chaque élément de donnée doit être traité de la même manière. Par exemple, vous pouvez parcourir les données en boucle, en traitant chaque élément de la même manière.
Les données ont un ordre naturel, par exemple, chronologique.
Exemples¶
L’exemple suivant montre la sortie d’une commande DESC TABLE sur une table avec des données VARIANT, ARRAY et OBJECT.
CREATE OR REPLACE TABLE test_semi_structured(
var VARIANT,
arr ARRAY,
obj OBJECT);
DESC TABLE test_semi_structured;
+------+---------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------+
| name | type | kind | null? | default | primary key | unique key | check | expression | comment | policy name | privacy domain |
|------+---------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------|
| VAR | VARIANT | COLUMN | Y | NULL | N | N | NULL | NULL | NULL | NULL | NULL |
| ARR | ARRAY | COLUMN | Y | NULL | N | N | NULL | NULL | NULL | NULL | NULL |
| OBJ | OBJECT | COLUMN | Y | NULL | N | N | NULL | NULL | NULL | NULL | NULL |
+------+---------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------+
Cet exemple montre comment charger des valeurs simples dans une table et à quoi ressemblent ces valeurs lorsque vous interrogez la table.
Créer une table et charger les données :
CREATE TABLE demonstration1 (
ID INTEGER,
array1 ARRAY,
variant1 VARIANT,
object1 OBJECT);
INSERT INTO demonstration1 (id, array1, variant1, object1)
SELECT
1,
ARRAY_CONSTRUCT(1, 2, 3),
PARSE_JSON(' { "key1": "value1", "key2": "value2" } '),
PARSE_JSON(' { "outer_key1": { "inner_key1A": "1a", "inner_key1B": "1b" }, '
||
' "outer_key2": { "inner_key2": 2 } } ');
INSERT INTO demonstration1 (id, array1, variant1, object1)
SELECT
2,
ARRAY_CONSTRUCT(1, 2, 3, NULL),
PARSE_JSON(' { "key1": "value1", "key2": NULL } '),
PARSE_JSON(' { "outer_key1": { "inner_key1A": "1a", "inner_key1B": NULL }, '
||
' "outer_key2": { "inner_key2": 2 } '
||
' } ');
Maintenant, affichez les données dans la table.
SELECT *
FROM demonstration1
ORDER BY id;
+----+-------------+---------------------+--------------------------+
| ID | ARRAY1 | VARIANT1 | OBJECT1 |
|----+-------------+---------------------+--------------------------|
| 1 | [ | { | { |
| | 1, | "key1": "value1", | "outer_key1": { |
| | 2, | "key2": "value2" | "inner_key1A": "1a", |
| | 3 | } | "inner_key1B": "1b" |
| | ] | | }, |
| | | | "outer_key2": { |
| | | | "inner_key2": 2 |
| | | | } |
| | | | } |
| 2 | [ | { | { |
| | 1, | "key1": "value1", | "outer_key1": { |
| | 2, | "key2": null | "inner_key1A": "1a", |
| | 3, | } | "inner_key1B": null |
| | undefined | | }, |
| | ] | | "outer_key2": { |
| | | | "inner_key2": 2 |
| | | | } |
| | | | } |
+----+-------------+---------------------+--------------------------+
Pour d’autres exemples, voir Interrogation de données semi-structurées.