- Les property graphs de Postgres 19 sont une fonctionnalité SQL/PGQ qui permet de déclarer des tables existantes comme sommets et arêtes, puis de rechercher des motifs relationnels fixes avec
MATCH, sans copier les données ni créer un moteur d’exécution graphe séparé
- Les motifs de graphe sont compilés en jointures relationnelles et réutilisent donc tels quels l’optimiseur, les index et les statistiques existants ; même les parcours lents peuvent être analysés et optimisés comme des jointures classiques
- Les tables de dimension se mappent naturellement en sommets, les tables de jointure pures en arêtes, mais les tables de faits avec plusieurs clés étrangères et leurs propres attributs sont mieux modélisées comme des sommets hub représentant des événements
- Une même table peut être déclarée simultanément comme sommet et comme plusieurs arêtes sous différents alias, ce qui signifie qu’avec les clés étrangères existantes de
results, il n’est pas nécessaire de créer ni stocker des tables d’arêtes séparées
- Postgres 19 ne prend pas en charge les chemins de longueur variable, ce qui le rend inadapté au plus court chemin, à l’atteignabilité en N sauts ou à PageRank, mais adapté aux explorations à longueur fixe dont la structure relationnelle est connue à l’avance
Lire un schéma relationnel comme un graphe
- Dans un schéma relationnel normalisé, des tables de dimension comme
drivers, constructors et circuits contiennent des entités, tandis que les tables de faits enregistrent des événements comme les résultats de course ou les sessions de qualifications
- Chaque ligne est un sommet potentiel, et chaque clé étrangère une arête potentielle pointant vers une autre ligne
- Un diagramme ER correspond à un graphe au niveau du schéma
- Les lignes réelles et les relations de clés étrangères correspondent à un graphe au niveau des instances
- Une demande comme « trouver le constructor correspondant à chaque résultat » est un parcours de graphe qui, en SQL relationnel, s’écrit
results JOIN constructors ON ...
- SQL/PGQ n’ajoute pas un nouveau graphe en soi ; il permet simplement de poser la question sous forme de graphe au lieu d’énumérer directement les jointures
- L’approche RelBench importe les tables dans pandas puis construit un graphe PyTorch en mémoire, tandis que les property graphs de Postgres réutilisent directement les relations existantes entre les tables de la base
- Les exemples de PyG utilisent eux aussi principalement des fichiers plats ou des graphes en mémoire
- Le code d’expérimentation sur le jeu de données Formula 1 est disponible dans le dépôt GitHub
Composition d’un property graph
CREATE PROPERTY GRAPH est un objet déclaratif nommé construit au-dessus de tables existantes
VERTEX TABLES indique quelles tables doivent être lues comme des sommets
EDGE TABLES indique quelles tables doivent être lues comme des relations de connexion
- Pour chaque table de sommets, on définit les éléments suivants
KEY : l’identifiant du sommet, généralement la clé primaire
LABEL : le nom du type de sommet utilisé dans MATCH
PROPERTIES : la liste des colonnes accessibles depuis les requêtes graphe
- Pour chaque table d’arêtes, on précise
SOURCE et DESTINATION, qui référencent chacun la clé d’un sommet
CREATE PROPERTY GRAPH ne déplace ni ne copie les données
- Les lignes restent dans leurs tables d’origine
- La déclaration définit seulement comment lire la structure de clés étrangères existante comme un graphe
- Les éléments structurels d’un property graph ne sont que de deux types : sommets et arêtes
- Les labels et les propriétés sont des attributs attachés à un sommet ou à une arête
- Dans
psql, la colonne Element Kind vaut soit vertex, soit edge
Interroger des motifs fixes avec MATCH
- Une requête graphe s’écrit en plaçant un motif
MATCH dans GRAPH_TABLE(...)
- Le motif suivant représente une relation allant de driver vers race en passant par result
MATCH (d IS driver)<-[IS of_driver]-(res IS result)-[IS in_race]->(ra IS race)
- La clause
COLUMNS définit les colonnes renvoyées par la requête graphe vers l’extérieur
- Dans le
SELECT externe, on peut interroger le résultat de GRAPH_TABLE(...) comme une table ordinaire
- Comme le motif inclut direction et labels, la relation se lit presque comme une phrase, ce qui la rend plus facile à comprendre qu’une jointure multiple équivalente
Une structure transformée à l’exécution en jointures relationnelles
MATCH n’est pas un moteur d’exécution graphe ajouté séparément à Postgres, mais une syntaxe compilée en jointures relationnelles
- Un
EXPLAIN du motif driver–result–race montre quatre jointures de hachage sur les tables sous-jacentes
- Comme avec des jointures écrites à la main, cela utilise
- l’optimiseur Postgres existant
- les index existants
- les statistiques existantes
- Si un parcours graphe est lent, les causes et les leviers d’optimisation sont les mêmes que pour une jointure classique lente
- Dans
psql, on peut aussi inspecter le graphe avec des commandes proches de celles des tables
\dG : affiche la liste des property graphs
\d f1 : montre chaque sommet et arête, la table sous-jacente, le type d’élément, ainsi que les sommets de départ et d’arrivée pour les arêtes
\d+ f1 : reconstitue l’instruction complète CREATE PROPERTY GRAPH, y compris les clés d’arêtes déduites à partir de la clé primaire des tables d’arêtes
Différence entre clés et propriétés
- Une colonne définie comme
KEY d’un sommet ne devient pas automatiquement une propriété
- Si
driver_id est défini uniquement comme clé de sommet, un filtre d.driver_id = 1 échoue parce que cette colonne n’est pas exposée comme propriété interrogeable
- La clé identifie le sommet, mais n’est pas automatiquement exposée à la requête
- Pour filtrer ou renvoyer une colonne ID, il faut l’ajouter explicitement à la liste
PROPERTIES
Limites des chemins de longueur variable dans Postgres 19
- Postgres 19 ne prend pas en charge les quantificateurs de motifs d’éléments permettant de suivre une arête de 1 à 3 fois
ERROR: element pattern quantifier is not supported
- Pour parcourir deux sauts, il faut écrire explicitement deux motifs d’arêtes dans
MATCH
- Il n’est pas possible d’exprimer des chemins de longueur arbitraire avec la syntaxe property graph
- Les explorations à profondeur ouverte doivent être traitées avec des CTE récursives sur les tables sous-jacentes, ce qui sort alors de la syntaxe property graph
Mapper des tables existantes en sommets et arêtes
-
Les tables de dimension comme sommets
- Les tables d’entités comme
drivers, constructors ou circuits, avec une clé primaire stable et des attributs, se prêtent directement à une modélisation en sommets
- Il suffit d’utiliser la clé primaire comme clé de sommet et d’exposer les colonnes nécessaires comme propriétés
-
Les tables de jointure pures comme arêtes
- Une table de pont plusieurs-à-plusieurs comme
student_courses(student_id, course_id) a pour rôle natif de relier deux entités, elle se mappe donc naturellement en arête
- On déclare une clé étrangère comme sommet source et l’autre comme sommet destination
- Chaque ligne de la table de jointure étant déjà une relation, aucune transformation spécifique aux graphes n’est nécessaire
- Dans cette structure,
students et courses deviennent des sommets, et student_courses devient l’arête enrolled_in
-
Les tables de faits comme sommets d’événements
- Une ligne
results pointe vers trois entités — driver, race et constructor — tout en portant aussi ses propres données comme grid, position, points et status
- Une arête SQL/PGQ est une relation binaire avec une seule source et une seule destination ; on ne peut donc pas transformer toute une ligne avec trois clés étrangères en une arête unique
- Si la ligne de fait elle-même est un objet d’analyse, il vaut mieux déclarer cette table comme sommet
- Le sommet
results porte alors l’événement et ses propriétés
- Des arêtes étroites comme
results_driver, results_race et results_constructor le relient aux entités externes
- Ce modèle crée une structure en hub du type
driver <- result -> race, où l’on peut s’arrêter au sommet result pour filtrer ou lire ses propriétés
- Si ce qui vous intéresse est la relation elle-même, modélisez-la comme une arête ; si c’est une ligne particulière ou un événement avec ses propres attributs, modélisez-la comme un sommet
- Une table de jointure représente une relation, une table de faits représente un événement
Utiliser une même table à la fois comme sommet et comme arête
- La distinction « sommet ou arête » ne s’applique pas à la table sous-jacente elle-même, mais à chaque déclaration d’élément du graphe
- Une même table peut être déclarée à la fois dans
VERTEX TABLES et dans EDGE TABLES sous des alias différents
- On peut utiliser
results comme sommet result tout en réutilisant la même table avec les alias d’arêtes suivants
results AS res_driver : relie result à driver
results AS res_race : relie result à race
results AS res_constr : relie result à constructor
- Chaque alias d’arête utilise les colonnes de clé primaire et de clé étrangère déjà présentes dans
results
- Il n’est pas nécessaire de créer des tables
results_driver, results_race ou results_constructor séparées, et les alias ne stockent aucune donnée
- Une table de faits avec trois clés étrangères ne doit pas être déclarée comme une arête à extrémités multiples, mais comme trois alias d’arêtes distincts, chacun avec une seule source et une seule destination
- Cette approche repose sur trois alias déclaratifs d’une seule table sous-jacente, plutôt que sur trois tables physiques ou vues
Conflits de noms et de types de propriétés
- Si
PROPERTIES est omis, SQL/PGQ expose toutes les colonnes de la table comme propriétés
- Si
results et qualifying possèdent tous deux une colonne number, mais respectivement de type double precision et bigint, l’erreur suivante se produit
ERROR: property "number" data type mismatch: double precision vs. bigint
- Dans l’ensemble du graphe, une propriété portant le même nom doit avoir un type unique ; des colonnes homonymes de types différents entrent donc en conflit
- En listant explicitement uniquement les colonnes nécessaires dans
PROPERTIES, on peut exclure du graphe les colonnes conflictuelles
- Le fait qu’une clé ne devienne pas automatiquement une propriété et les conflits de type se résolvent tous deux via une liste blanche explicite de propriétés
Requêtes adaptées et requêtes inadaptées
-
Motifs relationnels fixes
- Les property graphs conviennent bien aux questions du type « trouve les éléments connectés à X selon ce motif précis »
- Dans le graphe Formula 1, on peut écrire des requêtes comme
- explorer pour quels constructors un driver donné a couru
- trouver des rivaux via un motif allant de driver à result puis race, puis vers un autre result et un autre driver
- filtrer à la fois sur la structure et sur les propriétés, par exemple des résultats où la position de départ est au-delà de la 10e place et où le driver est italien
- Quand on connaît à l’avance la forme des relations et que cette structure est fixe et finie, la syntaxe de recherche, de filtrage et d’agrégation gagne en lisibilité
- Même des requêtes nécessitant plusieurs auto-jointures peuvent être exprimées de façon claire dans un seul motif
MATCH
-
Les problèmes où le chemin lui-même est inconnu
- Les problèmes suivants ne conviennent pas aux property graphs de Postgres 19
- le plus court chemin entre deux drivers
- tous les éléments atteignables en N sauts
- l’exploration de connexions dont la profondeur n’est pas connue à l’avance
- Ces requêtes exigent des parcours de longueur variable et doivent donc utiliser des CTE récursives sur les tables sous-jacentes
- Des algorithmes de graphe comme PageRank, la détection de communautés ou le calcul de centralité relèvent aussi d’un autre type de problème et ne font pas partie du périmètre de cette fonctionnalité
- Les property graphs servent à trouver ce qui est connecté quand on connaît déjà la structure du chemin, mais ils ne permettent pas de découvrir un chemin inconnu entre X et Y ni de calculer l’importance structurelle dans le graphe
Ce qu’il faut évaluer avant adoption
- SQL/PGQ est une surcouche déclarative posée sur la structure existante de clés étrangères, sans stockage de données supplémentaire sauf choix explicite contraire
- Il présente deux avantages principaux
- écrire des parcours de forme fixe de manière plus lisible qu’avec des jointures relationnelles
- fournir un objet nommé qui documente le schéma comme un graphe
- Sa plus grande limite est l’absence de chemins de longueur variable, qui impose de traiter les explorations profondes ou ouvertes avec du SQL récursif
- Une table n’est pas intrinsèquement un sommet ou une arête ; dans chaque graphe, on peut décider de lire ses lignes comme sommet, arête ou les deux
- Si vous voulez interroger des motifs de graphe fixes sur un schéma existant dans Postgres 19, il peut valoir la peine d’examiner
CREATE PROPERTY GRAPH et MATCH avant de déplacer les données vers une base de données graphe séparée
- Si vous devez explorer une profondeur inconnue, il faut des CTE récursives, mais quelle que soit l’approche, les données n’ont pas besoin de quitter Postgres
- Avant toute adoption réelle, il faut tester directement si les performances répondent au besoin
Aucun commentaire pour le moment.