Les magasins de documents NoSQL peuvent être idéaux pour gérer de grandes quantités de données non structurées. Cependant, certaines organisations travaillent avec des données non structurées, mais souhaitent toujours disposer des capacités offertes par les bases de données SQL traditionnelles. Par exemple, les médias ou les agences de presse peuvent gérer des sites web à fort trafic, centrés sur de grandes quantités de textes et d'images. Bien qu'elles aient besoin de stocker ces données non structurées, elles n'ont peut-être pas vraiment besoin des schémas flexibles ou de l'évolutivité horizontale qu'offrent les bases de données NoSQL. Ils ont plutôt besoin de la facilité de gestion et de la cohérence d'une base de données relationnelle comme PostgreSQL.
Est-il possible d'obtenir le meilleur des deux mondes ? Oui.
Avec ses types de données conçus pour supporter les données non structurées, PostgreSQL offre un juste milieu, vous permettant d'exploiter les capacités NoSQL au sein d'une base de données relationnelle qui est rentable et simple à gérer. Dans cet article, nous allons voir comment vous pouvez utiliser les types de données HStore et JSONB dans PostgreSQL pour travailler avec des données non structurées.
Avant d'entrer dans le vif du sujet, examinons brièvement les principales différences entre les bases de données SQL et NoSQL.
Comprendre SQL par rapport à NoSQL
Les bases de données SQL et NoSQL ont chacune leurs propres forces et faiblesses. Pour prendre une décision éclairée sur celle qui répondra le mieux à vos besoins en matière de données, vous devez bien comprendre les différences entre ces deux types de bases de données.
Les bases de données SQL (relationnelles), comme PostgreSQL et MySQL, représentent les données avec une structure claire et prévisible en tableaux, lignes et colonnes. Elles adhèrent aux propriétés ACID (atomicité, cohérence, isolation et durabilité), qui constituent une base solide pour l'intégrité des données en garantissant que les transactions de la base de données sont traitées de manière fiable.
Les bases de données SQL s'imposent lorsque la cohérence et l'intégrité des données sont cruciales, par exemple dans le cadre de requêtes complexes et de systèmes transactionnels (comme les applications financières).
En revanche, les bases de données NoSQL (magasins de documents) s'adressent à des ensembles de données vastes et variés qui ne conviennent pas nécessairement à une représentation tabulaire. MongoDB, Cassandra et Couchbase sont des exemples de bases de données NoSQL. Les bases de données NoSQL fonctionnent avec des schémas flexibles, ce qui permet aux structures de données d'évoluer au fil du temps. Elles prennent également en charge l'évolutivité horizontale, en répartissant les données sur plusieurs serveurs afin d'améliorer la gestion des charges de données importantes et du trafic élevé.
Les bases de données NoSQL sont souvent utilisées dans des applications où l'évolutivité est cruciale, par exemple pour traiter de grandes quantités de données dans des applications en temps réel ou de grands modèles de langage (LLM). Les bases de données NoSQL sont également utiles lorsqu'il s'agit de structures de données variées et évolutives, car elles permettent aux organisations de s'adapter à l'évolution de leurs besoins en matière de données.
Pourquoi utiliser PostgreSQL comme magasin de documents ?
PostgreSQL est une base de données relationnelle, il peut donc sembler peu conventionnel de la considérer comme une option pour répondre aux besoins NoSQL. Cependant, votre situation peut justifier l'utilisation de PostgreSQL en tant que magasin de documents.
Si vos besoins en matière de stockage de données sont diversifiés - nécessitant à la fois un stockage de données structuré et conforme à la norme ACID et un stockage de documents flexible et sans schéma - alors vous pouvez utiliser PostgreSQL pour combiner des modèles relationnels et non relationnels. Ou encore, vous souhaitez peut-être bénéficier de certaines fonctionnalités NoSQL, mais aussi des garanties de cohérence des données qui vont de pair avec les propriétés ACID. Enfin, en tant que technologie mature avec une communauté active, PostgreSQL apporte un support SQL complet, une indexation avancée et une recherche plein texte. Ces fonctionnalités, combinées à ses capacités NoSQL, font de PostgreSQL une solution de stockage de données polyvalente.
Limites de l'utilisation de PostgreSQL pour les données de type NoSQL
Malgré sa polyvalence, PostgreSQL présente certaines limites par rapport aux bases de données NoSQL traditionnelles. Alors que PostgreSQL peut évoluer verticalement, il ne supporte pas intrinsèquement l'évolution horizontale ou les données distribuées avec le sharding automatique, des fonctionnalités que les bases de données NoSQL offrent généralement. PostgreSQL n'offre pas non plus d'optimisations pour certaines structures de données NoSQL comme les magasins à colonnes larges ou les bases de données graphiques. Enfin, PostgreSQL n'offre pas de cohérence ajustable pour optimiser les performances, ce que vous pouvez obtenir avec certaines bases de données NoSQL.
Si vous envisagez d'utiliser PostgreSQL pour de grands ensembles de données non structurées, sachez que ces limitations peuvent avoir un impact sur les performances et votre capacité à évoluer. De plus, mélanger les opérations de données SQL et NoSQL introduit de la complexité. Une planification minutieuse et une bonne compréhension des deux paradigmes vous aideront à éviter les pièges potentiels.
Cependant, avec une bonne compréhension et un bon cas d'utilisation, PostgreSQL peut être un outil puissant, offrant le meilleur des deux mondes SQL et NoSQL.
HStore et JSONB dans PostgreSQL
Lorsque nous examinons les possibilités d'utilisation de PostgreSQL en tant que solution NoSQL, nous rencontrons trois types de données qui offrent des fonctionnalités similaires à celles de NoSQL, mais ils ont chacun des caractéristiques et des cas d'utilisation uniques.
- HStore: Ce type de données vous permet de stocker des paires clé-valeur dans une seule valeur PostgreSQL. Il est utile pour stocker des données semi-structurées qui n'ont pas de schéma fixe.
- JSONB: Il s'agit d'une représentation binaire de données de type JSON. Il peut stocker des structures plus complexes que HStore et prend en charge toutes les fonctionnalités JSON. JSONB est indexable, ce qui en fait un bon choix pour les grandes quantités de données.
- JSON: Ce type de données est similaire à JSONB, bien qu'il n'en possède pas les capacités et l'efficacité. Le type de données JSON stocke une copie exacte du texte d'entrée, qui inclut les espaces blancs et les clés dupliquées.
Nous mentionnons le type de données JSON comme un choix valable pour stocker des données formatées en JSON lorsque vous n'avez pas besoin de toutes les possibilités offertes par JSONB. Cependant, dans la suite de cet article, nous nous concentrerons principalement sur HStore et JSONB.
HStore
La documentation de PostgreSQL décrit HStore comme utile lorsque vous avez "des lignes avec de nombreux attributs qui sont rarement examinés, ou des données semi-structurées". Avant de pouvoir travailler avec le type de données HStore, assurez-vous d'activer l'extension HStore :
> CREATE EXTENSION hstore;
HStore est représenté par zéro ou plusieurs paires clé => valeur séparées par des virgules. L'ordre des paires n'est pas significatif et n'est pas conservé de manière fiable à la sortie.
> SELECT 'foo => bar, prompt => "hello world", pi => 3.14'::hstore;
hstore
-----------------------------------------------------
"pi"=>"3.14", "foo"=>"bar", "prompt"=>"hello world"
(1 row)
Chaque clé HStore est unique. Si une déclaration HStore est faite avec des clés dupliquées, un seul des duplicatas sera stocké, et il n'y a aucune garantie quant au choix de celui-ci.
> SELECT 'key => value1, key => value2'::hstore;
hstore
-----------------
"key"=>"value1"
(1 row)
Avec sa structure plate clé-valeur, HStore offre simplicité et rapidité d'interrogation, ce qui le rend idéal pour les scénarios simples. Cependant, HStore ne prend en charge que les données textuelles et ne prend pas en charge les données imbriquées, ce qui le rend limité pour les structures de données complexes.
D'autre part, JSONB peut gérer une plus grande variété de types de données.
JSONB
Le type de données JSONB accepte le texte d'entrée formaté JSON et le stocke dans un format binaire décomposé. Bien que cette conversion ralentisse légèrement la saisie, le résultat est un traitement rapide et une indexation efficace. JSONB ne préserve pas les espaces blancs ni l'ordre des clés des objets.
> SELECT '{"foo": "bar", "pi": 3.14, "nested": { "prompt": "hello", "count": 5 } }'::jsonb;
jsonb
-----------------------------------------------------------------------
{"pi": 3.14, "foo": "bar", "nested": {"count": 5, "prompt": "hello"}}
(1 row)
Si des clés d'objet sont données en double, la dernière valeur est conservée.
> SELECT '{"key": "value1", "key": "value2"}'::jsonb;
jsonb
-------------------
{"key": "value2"}
(1 row)
Parce que JSONB prend en charge les structures complexes et les capacités JSON complètes, c'est le choix idéal pour les données complexes ou imbriquées, préférable à HStore ou JSON. Cependant, l'utilisation de JSONB entraîne une surcharge de performance et une utilisation accrue du stockage par rapport à HStore.
Exemples pratiques : Travailler avec HStore et JSONB
Prenons quelques exemples pratiques pour montrer comment travailler avec ces types de données. Nous étudierons la création de tables, les requêtes et les opérations de base, ainsi que l'indexation.
Opérations de base de HStore
Comme pour tout autre type de données, vous pouvez définir les champs de votre table de données PostgreSQL en tant que type de données HStore.
> CREATE TABLE articles ( id serial primary key, title varchar(64), meta hstore );
L'insertion d'un enregistrement avec un attribut HStore se présente comme suit :
> INSERT INTO articles (title, meta)
VALUES (
'Data Types in PostgreSQL',
'format => blog, length => 1350, language => English, license => "Creative Commons"');
> SELECT * FROM articles;
id | title | meta ----+--------------------------+------------------------------------------ 1 | Data Types in PostgreSQL | "format"=>"blog", "length"=>"1350", "license"=>"Creative Commons", "language"=>"English"(1 row)
Avec les champs HStore, vous pouvez récupérer des paires clé-valeur spécifiques dans le champ, comme spécifié par les clés que vous fournissez :
> SELECT title, meta -> 'license' AS license, meta -> 'format' AS format FROM articles;
title | license | format
---------------------------------+------------------+------------
Data Types in PostgreSQL | Creative Commons | blog
Advanced Querying in PostgreSQL | None | blog
Scaling PostgreSQL | MIT | blog
PostgreSQL Fundamentals | Creative Commons | whitepaper
(4 rows)
Vous pouvez également effectuer des requêtes avec des critères basés sur des valeurs spécifiques dans un champ HStore.
> SELECT id, title FROM articles WHERE meta -> 'license' = 'Creative Commons';
id | title
----+--------------------------
1 | Data Types in PostgreSQL
4 | PostgreSQL Fundamentals
(2 rows)
Il peut arriver que vous ne souhaitiez interroger que les lignes contenant une clé spécifique dans le champ HStore. Par exemple, la requête suivante ne renvoie que les lignes dont le méta HStore contient la clé note. Pour ce faire, vous devez utiliser l'opérateur ?
> SELECT title, meta->'note' AS note FROM articles WHERE meta ? 'note';
title | note
---------------------------------+-----------------
PostgreSQL Fundamentals | hold for review
Advanced Querying in PostgreSQL | needs edit
(2 rows)
Une liste d'opérateurs et de fonctions HStore utiles est disponible ici. Par exemple, vous pouvez extraire les clés d'un HStore dans un tableau, ou vous pouvez convertir un HStore en une représentation JSON.
> SELECT title, akeys(meta) FROM articles where id=1;
title | akeys
--------------------------+----------------------------------
Data Types in PostgreSQL | {format,length,license,language}
(1 row)
> SELECT title, hstore_to_json(meta) FROM articles where id=1;
title | hstore_to_json
--------------------------+------------------------------------------------
Data Types in PostgreSQL | {"format": "blog", "length": "1350", "license": "Creative Commons", "language": "English"}
(1 row)
Opérations de base de JSONB
Travailler avec le type de données JSONB dans PostgreSQL est simple. La création d'une table et l'insertion d'un enregistrement ressemblent à ceci :
> CREATE TABLE authors (id serial primary key, name varchar(64), meta jsonb);
> INSERT INTO authors (name, meta) VALUES ('Adam Anderson', '{ "active":true, "expertise": ["databases", "data science"], "country": "UK" }');
Notez que le champ méta jsonb est fourni sous la forme d'une chaîne de texte au format JSON. PostgreSQL se plaindra si la valeur que vous fournissez n'est pas un JSON valide.
> INSERT INTO authors (name, meta) VALUES ('Barbara Brandini', '{ "this is not valid JSON" }');
ERROR: invalid input syntax for type json
Contrairement au type HStore, JSONB prend en charge les données imbriquées.
> INSERT INTO authors (name, meta) VALUES ('Barbara Brandini', '{ "active":true, "expertise": ["AI/ML"], "country": "CAN", "contact": { "email": "[email protected]", "phone": "111-222-3333" } }');
Comme pour HStore, les champs JSONB peuvent être récupérés partiellement, avec seulement certaines clés. Par exemple, les champs JSONB peuvent être récupérés partiellement, avec seulement certaines clés :
> SELECT name, meta -> 'country' AS country FROM authors;
name | country ------------------+--------- Adam Anderson | "UK" Barbara Brandini | "CAN" Charles Cooper | "UK"(3 rows)
Le type de données JSONB possède de nombreux opérateurs dont l'utilisation est similaire à celle de HStore. Par exemple, l'utilisation suivante de l'opérateur ? permet de récupérer uniquement les lignes dont le champ méta contient la clé du contact.
> SELECT name, meta -> 'active' AS active, meta -> 'contact' AS contact FROM authors WHERE meta ? 'contact';
name | active | contact
------------------+--------+-----------------------------------------------
Barbara Brandini | true | {"email": "[email protected]", "phone": "111-222-3333"}
Charles Cooper | false | {"email": "[email protected]"}
(2 rows)
Travailler avec des index
Selon la documentation, le type de données HStore "prend en charge les index GiST et GIN pour les opérateurs @>, ?, ?& et ?|". Pour une explication détaillée des différences entre les deux types d'index, voir ici. L'indexation pour JSONB utilise les index GIN pour faciliter la recherche efficace de clés ou de paires clé-valeur.
La déclaration de création d'un index est conforme à ce que l'on peut attendre :
> CREATE INDEX idx_hstore ON articles USING GIN(meta);
> CREATE INDEX idx_jsonb ON authors USING GIN(meta);
Structure SQL avec flexibilité NoSQL
Revenons sur le cas d'utilisation initial que nous avons mentionné dans l'introduction. Imaginons une agence de presse qui stocke ses articles de la même manière qu'un magasin de documents NoSQL. L'article peut être représenté en JSON sous la forme d'un tableau ordonné d'objets représentant des sections, chacune ayant un contenu textuel, des notations et un formatage. En outre, un ensemble de métadonnées est associé à chaque article, et ces attributs de métadonnées ne sont pas cohérents d'un article à l'autre.
La description ci-dessus englobe la majeure partie des besoins NoSQL de l'organisation, mais tout le reste de la façon dont elle gère et organise ses données s'aligne étroitement sur un modèle de données relationnel.
En combinant les capacités NoSQL d'un type de données comme JSONB avec les forces traditionnelles SQL de PostgreSQL, l'organisation peut bénéficier de schémas flexibles et de requêtes rapides dans des données imbriquées, tout en étant capable d'effectuer des opérations conjointes et de renforcer les relations entre les données. Les types de données HStore et JSONB de PostgreSQL offrent des options puissantes aux développeurs qui ont besoin de la structure d'une base de données relationnelle mais aussi d'un stockage de données de type NoSQL.
PostgreSQL à l'échelle
Vous souhaitez prendre en charge le stockage et l'interrogation de données de type NoSQL tout en restant dans le cadre d'une base de données relationnelle traditionnelle ? Votre organisation traite peut-être des documents de la même manière que nous l'avons décrit dans ce billet. Ou peut-être cherchez-vous des options pour gérer le stockage de données non structurées pour un grand modèle de langage (LLM) ou tout autre projet d'IA/ML.
Le cluster PostgreSQL de la place de marché Linode vous offre le modèle relationnel et la structure d'une base de données SQL ainsi que l'évolutivité horizontale d'une base de données NoSQL. Combinez cela avec l'utilisation des types de données HStore ou JSONB, et vous avez une solution hybride idéale pour exploiter les capacités NoSQL lorsque vous travaillez avec PostgreSQL.
Commentaires