Types de données avancés PostgreSQL

PostgreSQLBeginner
Pratiquer maintenant

Introduction

Dans ce laboratoire, vous explorerez les types de données avancés de PostgreSQL, en vous concentrant sur JSON/JSONB, les tableaux (arrays) et les UUID. Vous apprendrez à stocker, interroger et manipuler des données au sein de ces types.

Le laboratoire commence par démontrer comment stocker et interroger des données JSON et JSONB, y compris la création d'une table avec une colonne JSONB, l'insertion de données JSON et l'utilisation d'opérateurs tels que -> et ->> pour extraire des valeurs spécifiques. Vous apprendrez ensuite les colonnes de tableaux (array columns) et les UUID.

Stocker et interroger des données JSON et JSONB

Dans cette étape, vous apprendrez à stocker et à interroger des données JSON et JSONB dans PostgreSQL. PostgreSQL fournit deux types de données pour stocker des données JSON : JSON et JSONB. Le type de données JSON stocke une copie exacte du texte d'entrée JSON, tandis que le type de données JSONB stocke les données JSON dans un format binaire décomposé. JSONB est généralement préféré car il offre de meilleures performances pour l'interrogation et l'indexation.

Commençons par ouvrir le shell PostgreSQL. Connectez-vous d'abord à la base de données labex :

sudo -u postgres psql -d labex

Vous devriez voir l'invite PostgreSQL :

labex=#

Maintenant, créons une table pour stocker des données JSONB :

CREATE TABLE products (id SERIAL PRIMARY KEY, data JSONB);

Cette commande SQL crée une table nommée products. La table comporte deux colonnes : id (une clé primaire entière auto-incrémentée) et data (une colonne JSONB pour stocker des données JSON).

Vous devriez voir une sortie similaire à celle-ci :

CREATE TABLE

Maintenant, insérons des données dans la table products :

INSERT INTO products (data) VALUES ('{"name": "Laptop", "price": 1200, "features": ["16GB RAM", "512GB SSD"]}');
INSERT INTO products (data) VALUES ('{"name": "Keyboard", "price": 75, "features": ["Mechanical", "RGB Backlight"]}');

Ces commandes insèrent deux lignes dans la table products. Chaque ligne contient un objet JSON avec des informations sur un produit.

Vous devriez voir une sortie similaire à celle-ci pour chaque insertion :

INSERT 0 1

Pour interroger les données JSON, vous pouvez utiliser les opérateurs -> et ->>. L'opérateur -> renvoie un objet JSON, tandis que l'opérateur ->> renvoie une valeur JSON sous forme de texte.

Par exemple, pour récupérer le nom du premier produit, vous pouvez utiliser la requête suivante :

SELECT data ->> 'name' FROM products WHERE id = 1;

Cette commande sélectionne la valeur associée à la clé name dans la colonne data de la table products, où l'id est 1. L'opérateur ->> garantit que le résultat est renvoyé sous forme de texte.

Vous devriez voir une sortie similaire à celle-ci :

  ?column?
----------
 Laptop
(1 row)

Vous pouvez également interroger des objets JSON imbriqués. Par exemple, pour récupérer la première fonctionnalité du premier produit, vous pouvez utiliser la requête suivante :

SELECT data -> 'features' ->> 0 FROM products WHERE id = 1;

Cette commande sélectionne d'abord le tableau features de la colonne data, puis sélectionne l'élément à l'indice 0 du tableau. L'opérateur ->> garantit que le résultat est renvoyé sous forme de texte.

Vous devriez voir une sortie similaire à celle-ci :

  ?column?
----------
 16GB RAM
(1 row)

Vous pouvez également utiliser l'opérateur @> pour vérifier si un objet JSON contient une paire clé-valeur spécifique. Par exemple, pour trouver tous les produits avec un prix de 75, vous pouvez utiliser la requête suivante :

SELECT data ->> 'name' FROM products WHERE data @> '{"price": 75}';

Cette commande sélectionne le nom de toutes les lignes de la table products où la colonne data contient un objet JSON avec une clé price et une valeur de 75.

Vous devriez voir une sortie similaire à celle-ci :

  ?column?
----------
 Keyboard
(1 row)

Excellent ! Nous avons créé avec succès notre première table avec des données JSONB et appris à l'interroger. Nous continuerons à travailler avec cette table dans l'étape suivante pour ajouter des fonctionnalités plus avancées.

Ajouter des colonnes de tableaux à une table existante

Dans cette étape, vous apprendrez à ajouter et à manipuler des colonnes de tableaux (array columns) dans PostgreSQL. Nous allons étendre notre table products existante en ajoutant une colonne de tableau pour stocker des tags. Les colonnes de tableaux vous permettent de stocker plusieurs valeurs du même type de données dans une seule colonne, ce qui est utile pour stocker des listes d'éléments tels que des tags, des catégories ou des fonctionnalités.

Étant donné que nous sommes déjà connectés à la base de données et que nous avons notre table products de l'étape précédente, ajoutons des colonnes de tableaux à notre table existante :

ALTER TABLE products ADD COLUMN name VARCHAR(255);
ALTER TABLE products ADD COLUMN tags TEXT[];

Ces commandes ajoutent deux nouvelles colonnes à notre table products existante : name (une chaîne de caractères) et tags (un tableau de chaînes de caractères). Le type de données TEXT[] spécifie que la colonne tags est un tableau de valeurs textuelles.

Vous devriez voir une sortie similaire à celle-ci pour chaque commande ALTER :

ALTER TABLE

Maintenant, mettons à jour nos données existantes et insérons de nouvelles données avec les nouvelles colonnes :

UPDATE products SET name = data ->> 'name' WHERE id = 1;
UPDATE products SET name = data ->> 'name' WHERE id = 2;
UPDATE products SET tags = ARRAY['electronics', 'computers', 'portable'] WHERE id = 1;
UPDATE products SET tags = ARRAY['electronics', 'accessories', 'input'] WHERE id = 2;

Ces commandes mettent à jour nos produits existants avec des informations de nom et de tags extraites des données JSONB et de nouvelles valeurs de tableaux.

Vous devriez voir une sortie similaire à celle-ci pour chaque mise à jour :

UPDATE 1

Pour interroger les données de tableaux, vous pouvez utiliser l'indexation de tableaux. Les indices de tableaux dans PostgreSQL commencent à 1.

Par exemple, pour récupérer le premier tag du premier produit, vous pouvez utiliser la requête suivante :

SELECT tags[1] FROM products WHERE id = 1;

Cette commande sélectionne l'élément à l'indice 1 du tableau tags de la table products, où l'id est 1.

Vous devriez voir une sortie similaire à celle-ci :

   tags
-----------
 electronics
(1 row)

Vous pouvez également utiliser la fonction UNNEST pour développer un tableau en un ensemble de lignes.

Par exemple, pour récupérer tous les tags de tous les produits, vous pouvez utiliser la requête suivante :

SELECT name, UNNEST(tags) AS tag FROM products;

Cette commande sélectionne le name et chaque tag individuel du tableau tags, créant une nouvelle ligne pour chaque tag.

Vous devriez voir une sortie similaire à celle-ci :

  name   |     tag
---------+-------------
 Laptop  | electronics
 Laptop  | computers
 Laptop  | portable
 Keyboard| electronics
 Keyboard| accessories
 Keyboard| input
(6 rows)

Vous pouvez utiliser l'opérateur @> pour vérifier si un tableau contient une valeur spécifique.

Par exemple, pour trouver tous les produits avec le tag 'electronics', vous pouvez utiliser la requête suivante :

SELECT name FROM products WHERE tags @> ARRAY['electronics'];

Cette commande sélectionne le nom de toutes les lignes de la table products où le tableau tags contient la valeur 'electronics'.

Vous devriez voir une sortie similaire à celle-ci :

  name
----------
 Laptop
 Keyboard
(2 rows)

Vous pouvez également utiliser l'opérateur && pour vérifier si deux tableaux ont des éléments en commun.

Par exemple, pour trouver tous les produits qui partagent des tags avec le premier produit, vous pouvez utiliser la requête suivante :

SELECT p2.name FROM products p1, products p2 WHERE p1.id = 1 AND p1.tags && p2.tags AND p2.id != 1;

Cette commande sélectionne le nom de toutes les lignes de la table products (aliassée p2) qui ont au moins un tag en commun avec les tags du premier produit (aliassé p1), en excluant le premier produit lui-même.

Vous devriez voir une sortie similaire à celle-ci :

  name
----------
 Keyboard
(1 row)

Parfait ! Nous avons ajouté avec succès des colonnes de tableaux à notre table existante et appris à travailler avec les tableaux. Notre table products contient maintenant des types de données JSONB et de tableaux, la rendant prête pour la prochaine étape.

Ajouter une colonne UUID et apprendre la génération d'UUID

Dans cette étape, vous apprendrez à générer et à utiliser des UUID (Universally Unique Identifiers) dans PostgreSQL. Les UUID sont des nombres de 128 bits conçus pour être uniques dans l'espace et le temps. Ils sont souvent utilisés comme identifiants uniques dans les tables de base de données pour éviter les conflits lors de la fusion de données provenant de différentes sources.

Puisque nous continuons avec notre session et notre table existantes, nous allons ajouter une colonne UUID à notre table products actuelle pour démontrer la fonctionnalité des UUID.

Tout d'abord, activons l'extension UUID qui fournit les fonctions de génération d'UUID :

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

Cette commande crée l'extension uuid-ossp si elle n'existe pas déjà.

Vous devriez voir une sortie similaire à celle-ci :

CREATE EXTENSION

Maintenant, ajoutons une colonne UUID à notre table products existante :

ALTER TABLE products ADD COLUMN uuid_id UUID;

Cette commande ajoute une nouvelle colonne UUID à notre table products existante.

Vous devriez voir une sortie similaire à celle-ci :

ALTER TABLE

Nous pouvons maintenant mettre à jour nos lignes existantes avec des valeurs UUID en utilisant la fonction uuid_generate_v4() :

UPDATE products SET uuid_id = uuid_generate_v4() WHERE id = 1;
UPDATE products SET uuid_id = uuid_generate_v4() WHERE id = 2;

Ces commandes mettent à jour nos produits existants avec des valeurs UUID uniques. La fonction uuid_generate_v4() génère un nouvel UUID pour chaque ligne.

Vous devriez voir une sortie similaire à celle-ci pour chaque mise à jour :

UPDATE 1

Pour interroger les données à l'aide des UUID, vous pouvez utiliser les valeurs UUID dans vos clauses WHERE. Comme les UUID sont générés aléatoirement, visualisons d'abord nos données actuelles :

SELECT id, name, uuid_id FROM products;

Cette commande sélectionne toutes les colonnes de la table products pour voir les UUID générés à côté de nos autres données.

Vous devriez voir une sortie similaire à celle-ci (votre UUID sera différent) :

                  id
------------------------------------
 a1b2c3d4-e5f6-7890-1234-567890abcdef
(1 row)

Maintenant, utilisez cet UUID dans la commande suivante, en remplaçant <YOUR_UUID_HERE> par l'UUID réel que vous avez récupéré :

SELECT name FROM products WHERE id = '<YOUR_UUID_HERE>';

Cette commande sélectionne le name de la table products où l'id correspond à l'UUID spécifié.

Vous devriez voir une sortie similaire à celle-ci (selon l'UUID que vous avez choisi) :

  name
----------
 Laptop
(1 row)

Enfin, nettoyons la table et l'extension que nous avons créées :

DROP TABLE products;
DROP EXTENSION "uuid-ossp";

Vous devriez voir une sortie similaire à celle-ci pour chaque commande DROP :

DROP TABLE
DROP EXTENSION

Extraire des données de types avancés

Dans cette dernière étape, vous pratiquerez l'extraction de données de tous les types de données avancés que nous avons ajoutés à notre table products tout au long de ce laboratoire. Notre table contient désormais des colonnes JSONB, de tableaux (array) et UUID, offrant un exemple complet des types de données avancés de PostgreSQL.

Puisque nous continuons avec notre session et notre table existantes, nous pouvons immédiatement commencer à travailler avec les données que nous avons accumulées au cours des étapes précédentes.

Tout d'abord, ajoutons des données JSONB supplémentaires pour rendre nos exemples d'extraction plus complets :

UPDATE products SET data = '{"brand": "Dell", "model": "XPS 13", "specs": {"ram": "16GB", "storage": "512GB SSD"}, "warranty": "3 years"}' WHERE id = 1;
UPDATE products SET data = '{"brand": "Logitech", "model": "G915", "specs": {"type": "Mechanical", "backlight": "RGB"}, "warranty": "2 years"}' WHERE id = 2;

Ces commandes mettent à jour nos données JSONB existantes avec des informations plus détaillées, y compris des objets imbriqués et des champs supplémentaires.

Vous devriez voir une sortie similaire à celle-ci pour chaque mise à jour :

UPDATE 1

Pratiquons maintenant l'extraction de données de tous nos types de données avancés. Pour extraire des données de la colonne JSONB data, vous pouvez utiliser les opérateurs -> et ->>. Par exemple, pour extraire la marque de nos données mises à jour :

SELECT data ->> 'brand' FROM products WHERE id = 1;

Cette commande récupère la valeur associée à la clé brand de la colonne data.

Vous devriez voir une sortie similaire à celle-ci :

 ?column?
----------
 Dell
(1 row)

Pour extraire des données imbriquées de la colonne JSONB, vous pouvez chaîner les opérateurs -> et ->>. Par exemple, pour extraire la spécification RAM :

SELECT data -> 'specs' ->> 'ram' FROM products WHERE id = 1;

Cette commande récupère la valeur associée à la clé ram dans l'objet specs.

Vous devriez voir une sortie similaire à celle-ci :

 ?column?
----------
 16GB
(1 row)

Pour extraire des données de la colonne tags (tableau), vous pouvez utiliser l'indexation de tableaux, comme appris à l'étape 2. Par exemple, pour extraire le premier tag du premier produit :

SELECT tags[1] FROM products WHERE id = 1;

Cette commande récupère l'élément à l'indice 1 du tableau tags de la table products où l'id est 1.

Vous devriez voir une sortie similaire à celle-ci :

   tags
-----------
 electronics
(1 row)

Créons maintenant une requête complète qui extrait des données de tous nos types de données avancés : JSONB, tableaux et UUID :

SELECT
    id,
    name,
    data ->> 'brand' AS brand,
    data -> 'specs' ->> 'ram' AS ram,
    tags[1] AS first_tag,
    uuid_id
FROM products;

Cette commande récupère des données de tous les types de données avancés avec lesquels nous avons travaillé : l'id entier, le name, la brand de la colonne JSONB data, la spécification ram imbriquée, le premier élément du tableau tags, et l'uuid_id.

Vous devriez voir une sortie similaire à celle-ci :

   name   |  ?column?  |   tags
----------+------------+-----------
 Laptop   | Dell       | electronics
 Keyboard | Logitech   | electronics
(2 rows)

Excellent ! Vous avez travaillé avec succès avec les trois types de données avancés de PostgreSQL dans une seule table. Cet exemple complet démontre comment JSONB, les tableaux et les UUID peuvent être utilisés ensemble pour créer des schémas de base de données flexibles et puissants.

Lorsque vous aurez terminé toutes les étapes, vous pourrez quitter le shell PostgreSQL en tapant :

\q

Vous pouvez également choisir de conserver la table pour des expérimentations supplémentaires avec les types de données avancés de PostgreSQL.

Résumé

Dans ce laboratoire, vous avez progressivement construit et travaillé avec une table products complète qui démontre les types de données avancés de PostgreSQL en action. Vous avez commencé par créer une table avec des colonnes JSONB et avez appris à stocker et interroger des données JSON en utilisant des opérateurs tels que -> et ->>.

Vous avez ensuite étendu la table en ajoutant des colonnes de tableaux (array), apprenant à stocker plusieurs valeurs dans une seule colonne et à les interroger à l'aide de l'indexation de tableaux et de fonctions comme UNNEST. Ensuite, vous avez ajouté la fonctionnalité UUID en activant l'extension uuid-ossp et en ajoutant une colonne UUID pour générer des identifiants uniques.

Enfin, vous avez pratiqué des techniques d'extraction de données complètes qui ont combiné les trois types de données avancés – JSONB, tableaux et UUID – dans des requêtes sophistiquées. Cette approche étape par étape a démontré comment ces types de données peuvent fonctionner ensemble dans des schémas de base de données réels, offrant flexibilité et capacités d'interrogation puissantes pour les applications modernes.