Introduction aux données semi-structurées

Les données semi-structurées sont des données qui ne sont pas conformes aux normes des données structurées classiques, mais qui contiennent des balises ou d’autres types de balisage qui identifient des entités individuelles et distinctes dans les données.

Deux des attributs de clé qui distinguent les données semi-structurées des données structurées sont les structures de données imbriquées et l’absence d’un schéma fixe :

  • Les données structurées nécessitent un schéma fixe qui est défini avant que les données puissent être chargées et interrogées dans un système de base de données relationnelle. Les données semi-structurées ne nécessitent pas de définition préalable d’un schéma et peuvent évoluer constamment, c’est-à-dire que de nouveaux attributs peuvent être ajoutés à tout moment.

    De plus, les entités d’une même classe peuvent avoir des attributs différents même si elles sont regroupées, et l’ordre des attributs ne joue aucun rôle.

  • Contrairement aux données structurées, qui représentent les données sous forme de table plate, les données semi-structurées peuvent contenir des hiérarchies d’informations imbriquées à n niveaux.

Dans ce chapitre :

Chargement de données semi-structurées

Les étapes de chargement des données semi-structurées vers des tables sont identiques à celles du chargement des données structurées vers des tables relationnelles.

Snowflake charge des données semi-structurées dans une seule colonne VARIANT. L’autre méthode consiste à utiliser une instruction de table COPY INTO avec transformation de données, ce qui vous permet d’extraire les colonnes sélectionnées d’un fichier de données préparé vers des colonnes de table séparées.

Formats de fichier pris en charge

Qu’est-ce que JSON ?

JSON (notation d’objet JavaScript) est un format d’échange de données léger, en texte clair, basé sur un sous-ensemble du langage de programmation JavaScript.

N’importe quelle application peut produire des données JSON. En voici quelques exemples classiques :

  • Applications JavaScript utilisant des méthodes natives pour générer des données JSON.

  • Applications non-JavaScript utilisant des bibliothèques (généralement avec des extensions) pour générer des données JSON.

  • Générateurs ad hoc JavaScript.

  • Concaténation de documents JSON (qui peuvent ou non être séparés par des lignes).

Puisqu’il n’y a pas de spécification formelle, il y a des différences significatives entre les différentes implémentations. Ces différences rendent impossible l’importation d’ensembles de données de type JSON si l’analyseur JSON est strict dans sa définition de langage. Pour rendre l’importation des ensembles de données JSON aussi facile que possible, Snowflake prône la libéralité. Le but est d’accepter la gamme la plus large possible d’entrées JSON et semblables à JSON qui permettent une interprétation sans ambiguïté.

Ce chapitre décrit la syntaxe des documents JSON acceptés par Snowflake.

Pour plus d’informations sur JSON, voir json.org.

Syntaxe JSON de base

Les données JSON sont un ensemble hiérarchique de paires nom/valeur regroupées en objets et tableaux :

  • Les deux points : séparent les noms et les valeurs dans les paires nom/valeur.

  • Les accolades {} indiquent des objets.

  • Les crochets [] indiquent des tableaux.

  • Les virgules , séparent les entités dans les objets et tableaux.

Paires nom/valeur

Les paires nom/valeur JSON se composent d’un nom de champ (entre guillemets doubles) suivi de deux points, puis d’une valeur.

Par exemple :

{"firstName":"John", "empid":45611}

Types de données pris en charge

Une valeur dans une paire nom/valeur peut être :

  • Un nombre (entier ou virgule flottante)

  • Une chaîne (entre guillemets doubles)

  • Un booléen (vrai ou faux)

  • Un tableau (entre crochets)

  • Un objet (entre accolades)

  • Nul

Objets

Les objets JSON s’écrivent dans des accolades. Un objet peut contenir plusieurs paires nom/valeur séparées par des virgules. Par exemple :

{"firstName":"John", "lastName":"Doe"}

Tableaux

Les tableaux JSON s’écrivent entre crochets. Un tableau peut contenir plusieurs objets séparés par des virgules. Par exemple :

{"employees":[
    {"firstName":"John", "lastName":"Doe"},
    {"firstName":"Anna", "lastName":"Smith"},
    {"firstName":"Peter", "lastName":"Jones"}
  ]
}

Exemples de documents JSON

FILE NAME : json_sample_data1

Contient un tableau avec 3 enregistrements d’employé simples (objets) :

{"root":[{"employees":[
    {"firstName":"John", "lastName":"Doe"},
    {"firstName":"Anna", "lastName":"Smith"},
    {"firstName":"Peter", "lastName":"Jones"}
]}]}

FILE NAME : json_sample_data2

Contient un tableau contenant 3 dossiers d’employé (objets) et les données connexes sur les personnes à leur charge (enfants, noms et âges des enfants, villes où l’employé a vécu et années pendant lesquelles l’employé a vécu dans ces villes) :

{"root":
   [
    { "kind": "person",
      "fullName": "John Doe",
      "age": 22,
      "gender": "Male",
      "phoneNumber":
        {"areaCode": "206",
         "number": "1234567"},
      "children":
         [
           {
             "name": "Jane",
             "gender": "Female",
             "age": "6"
           },
           {
              "name": "John",
              "gender": "Male",
              "age": "15"
           }
         ],
      "citiesLived":
         [
            {
               "place": "Seattle",
               "yearsLived": ["1995"]
            },
            {
               "place": "Stockholm",
               "yearsLived": ["2005"]
            }
         ]
      },
      {"kind": "person", "fullName": "Mike Jones", "age": 35, "gender": "Male", "phoneNumber": { "areaCode": "622", "number": "1567845"}, "children": [{ "name": "Earl", "gender": "Male", "age": "10"}, {"name": "Sam", "gender": "Male", "age": "6"}, { "name": "Kit", "gender": "Male", "age": "8"}], "citiesLived": [{"place": "Los Angeles", "yearsLived": ["1989", "1993", "1998", "2002"]}, {"place": "Washington DC", "yearsLived": ["1990", "1993", "1998", "2008"]}, {"place": "Portland", "yearsLived": ["1993", "1998", "2003", "2005"]}, {"place": "Austin", "yearsLived": ["1973", "1998", "2001", "2005"]}]},
      {"kind": "person", "fullName": "Anna Karenina", "age": 45, "gender": "Female", "phoneNumber": { "areaCode": "425", "number": "1984783"}, "citiesLived": [{"place": "Stockholm", "yearsLived": ["1992", "1998", "2000", "2010"]}, {"place": "Russia", "yearsLived": ["1998", "2001", "2005"]}, {"place": "Austin", "yearsLived": ["1995", "1999"]}]}
    ]
}

Qu’est-ce qu’Avro ?

Avro est un framework open source de sérialisation de données et de RPC développé à l’origine pour une utilisation avec Apache Hadoop. Il utilise des schémas définis dans JSON pour produire des données sérialisées dans un format binaire compact. Les données sérialisées peuvent être envoyées vers une destination quelconque (application ou programme) et peuvent être facilement désérialisées à la destination car le schéma est inclus dans les données.

Un schéma Avro est constitué d’une chaîne JSON, d’un objet ou d’un tableau qui définit le type de schéma et les attributs de données (noms de champ, types de données, etc.) pour ce type de schéma. Les attributs diffèrent selon le type de schéma. Les types de données complexes tels que les tableaux et les cartes sont pris en charge.

Snowflake lit les données Avro dans une seule colonne VARIANT. Vous pouvez interroger les données dans une colonne VARIANT comme vous le feriez avec des données JSON, en utilisant des commandes et fonctions similaires.

Pour plus d’informations, voir avro.apache.org.

Exemple d’un schéma Avro

{
 "type": "record",
 "name": "person",
 "namespace": "example.avro",
 "fields": [
     {"name": "fullName", "type": "string"},
     {"name": "age",  "type": ["int", "null"]},
     {"name": "gender", "type": ["string", "null"]}
     ]
}

Qu’est-ce que ORC ?

Utilisé pour stocker des données Hive, le format de fichier ORC (Optimized Row Columnar) a été conçu pour une compression efficace et des performances améliorées de la lecture, de l’écriture et du traitement de données par rapport aux formats de fichiers Hive précédents. Pour plus d’informations sur ORC, voir https://orc.apache.org/.

Snowflake lit les données ORC dans une seule colonne VARIANT . Vous pouvez interroger les données dans une colonne VARIANT comme vous le feriez avec des données JSON, en utilisant des commandes et fonctions similaires.

Vous pouvez également extraire des colonnes sélectionnées d’un fichier ORC préparé vers des colonnes de table séparées en utilisant une instruction CREATE TABLE AS SELECT.

ORC est un format binaire.

Note

  • La longueur maximale des colonnes binaires et de chaîne ORC est soumise à la limite Snowflake de 16 MB pour les données VARCHAR (compressées).

  • Les données de map sont désérialisées en un tableaux d’objets, par exemple :

    "map": [{"key": "chani", "value": {"int1": 5, "string1": "chani"}}, {"key": "mauddib", "value": {"int1": 1, "string1": "mauddib"}}]
    
  • Les données Union sont déserialisées en un objet unique, par exemple :

    {"time": "1970-05-05 12:34:56.197", "union": {"tag": 0, "value": 3880900}, "decimal": 3863316326626557453.000000000000000000}
    

Exemple de données ORC chargées dans une colonne VARIANT

+--------------------------------------+
| SRC                                  |
|--------------------------------------|
| {                                    |
|   "boolean1": false,                 |
|   "byte1": 1,                        |
|   "bytes1": "0001020304",            |
|   "decimal1": 12345678.654745,       |
|   "double1": -1.500000000000000e+01, |
|   "float1": 1.000000000000000e+00,   |
|   "int1": 65536,                     |
|   "list": [                          |
|     {                                |
|       "int1": 3,                     |
|       "string1": "good"              |
|     },                               |
|     {                                |
|       "int1": 4,                     |
|       "string1": "bad"               |
|     }                                |
|   ]                                  |
| }                                    |
+--------------------------------------+

Qu’est-ce que Parquet ?

Parquet est une représentation de données en colonnes compressée et efficaces conçue pour les projets dans l’écosystème Hadoop. Le format de fichier prend en charge les structures de données imbriquées complexes et utilise les algorithmes de déchiquetage et d’assemblage des enregistrements Dremel. Pour plus d’informations, voir parquet.apache.org/documentation/latest/.

Snowflake lit les données de Parquet dans une seule colonne VARIANT. Vous pouvez interroger les données dans une colonne VARIANT comme vous le feriez avec des données JSON, en utilisant des commandes et fonctions similaires.

Vous pouvez également extraire des colonnes sélectionnées d’un fichier Parquet préparé vers des colonnes de table séparées en utilisant une instruction CREATE TABLE AS SELECT.

Parquet est un format binaire. Il n’est pas possible de fournir un exemple de fichier Parquet.

Exemple de données Parquet chargées dans une colonne VARIANT

+------------------------------------------+
| SRC                                      |
|------------------------------------------|
| {                                        |
|   "continent": "Europe",                 |
|   "country": {                           |
|     "city": {                            |
|       "bag": [                           |
|         {                                |
|           "array_element": "Paris"       |
|         },                               |
|         {                                |
|           "array_element": "Nice"        |
|         },                               |
|         {                                |
|           "array_element": "Marseilles"  |
|         },                               |
|         {                                |
|           "array_element": "Cannes"      |
|         }                                |
|       ]                                  |
|     },                                   |
|     "name": "France"                     |
|   }                                      |
| }                                        |
+------------------------------------------+

Qu’est-ce que XML ?

XML (Extensible Markup Language) est un langage de balisage qui définit un ensemble de règles pour l’encodage de documents. Il était à l’origine basé sur SGML, un autre langage de balisage développé pour normaliser la structure et les éléments qui composent un document.

Depuis son introduction, XML s’est développé au-delà de la focalisation initiale sur les documents afin d’intégrer un large éventail d’utilisations, y compris la représentation de structures de données arbitraires, et de servir de langue de base aux protocoles de communication. En raison de son extensibilité, de sa polyvalence et de sa facilité d’utilisation, il est devenu l’un des standards les plus utilisés pour l’échange de données sur le Web.

Un document XML se compose principalement des constructions suivantes :

  • Balises (identifiées par des chevrons, < et >)

  • Éléments

Les éléments se composent généralement d’une balise « start » et d’une balise « end » correspondante, le texte entre les balises constituant le contenu de l’élément. Un élément peut également être composé d’une balise « empty-element » sans balise « end ». Les balises « start » et « empty-element » peuvent contenir des attributs qui aident à définir les caractéristiques ou les métadonnées de l’élément.

Exemple de document XML

<?xml version="1.0"?>
<!DOCTYPE parts system "parts.dtd">
<?xml-stylesheet type="text/css" href="xmlpartsstyle.css"?>
<parts>
   <title>Automobile Parts &amp; Accessories</title>
   <part>
      <item>Spark Plugs</item>
      <partnum>A3-400</partnum>
      <price> 27.00</price>
   </part>
   <part>
      <item>Motor Oil</item>
      <partnum>B5-200</partnum>
      <price> 14.00</price>
   </part>
   <part>
      <item>Motor Oil</item>
      <partnum>B5-300</partnum>
      <price> 16.75</price>
   </part>
   <part>
      <item>Engine Coolant</item>
      <partnum>B6-120</partnum>
      <price> 19.00</price>
   </part>
   <part>
      <item>Engine Coolant</item>
      <partnum>B6-220</partnum>
      <price> 18.25</price>
   </part>
</parts>