Présentation des graphiques créés à partir de vues SQL

Ce document vous explique les avantages de l'utilisation de vues SQL pour créer un graphique. Ce document inclut les avantages de la création de graphiques avec des vues, les exigences et les points à prendre en compte pour vous aider à décider si vous devez utiliser des tables ou des vues pour créer un graphique.

Pour savoir comment créer un graphique à partir de vues, consultez Créer un graphique de propriétés à partir de vues SQL.

Avantages de la création de graphiques avec des vues plutôt qu'avec des tableaux

Une vue SQL est une table virtuelle définie par une requête SQL. Dans Spanner, la requête qui définit une vue s'exécute chaque fois qu'une requête faisant référence à la vue s'exécute. Les vues Spanner ne sont pas des vues matérialisées, car elles ne stockent pas les résultats de la requête définissant la vue en tant que table réelle dans le stockage de données. Pour en savoir plus, consultez la Présentation des vues. Vous pouvez créer des éléments de graphique à partir de vues SQL, mais vous ne pouvez pas créer de vue qui interroge un graphique.

Les vues offrent plusieurs avantages en tant que couche d'abstraction entre les tables et un schéma de graphe, ce qui n'est pas le cas lorsque vous utilisez des tables pour créer un graphe.

Conditions requises pour utiliser des vues afin de créer des graphiques

Vous devez respecter les exigences suivantes lorsque vous utilisez des vues pour créer des éléments de graphique :

Utiliser la clause KEY lorsque vous spécifiez un élément de graphique

Vous devez définir explicitement les colonnes qui identifient de manière unique l'élément de graphique lorsque vous utilisez des vues pour créer un élément de nœud ou d'arête. Pour ce faire, utilisez la clause KEY dans la définition de l'élément de nœud ou d'arête. Pour savoir comment utiliser la clause KEY lors de la création d'un élément de graphique, consultez les exemples de code dans ce document et dans Créer un graphique Spanner à partir d'une vue SQL.

Utiliser des vues qui garantissent l'unicité des nœuds et des arêtes

Les vues qui définissent des tables de nœuds ou d'arêtes doivent suivre l'un des modèles suivants pour garantir l'unicité des nœuds et des arêtes :

  • Schéma 1 : La vue utilise la clé primaire d'une seule table.

  • Schéma 2 : La vue utilise une clause GROUP BY ou SELECT DISTINCT.

Vous pouvez utiliser d'autres opérateurs SQL tels que WHERE, HAVING, ORDER BY, LIMIT et TABLESAMPLE en combinaison avec ces modèles. Ces opérateurs filtrent ou trient les résultats, mais ne modifient pas la garantie d'unicité sous-jacente fournie par les modèles.

Schéma 1 : Utiliser la clé primaire d'une seule table

Dans ce modèle, la vue effectue une sélection à partir d'une seule table, et la clause KEY de la définition du graphique correspond aux colonnes de clé primaire de la table de base. Par conséquent, chaque ligne de nœud ou d'arête produite par la vue est unique.

Par exemple, la requête suivante sélectionne un sous-ensemble de lignes de la table Account. Le graphique KEY(account_id) correspond à la clé primaire de la table Account, ce qui garantit que chaque ligne produite par la vue est unique.

-- Table has PRIMARY KEY(account_id).
CREATE TABLE Account (
  account_id INT64 NOT NULL,
  customer_id INT64 NOT NULL,
  account_type STRING(MAX),
  balance INT64
) PRIMARY KEY(account_id);

-- Pattern 1: View uses the primary key from a single table.
CREATE VIEW SavingAccount
  SQL SECURITY INVOKER AS
    SELECT accnt.account_id, accnt.customer_id, accnt.balance
    FROM Account accnt
    WHERE accnt.account_type = 'saving';

CREATE PROPERTY GRAPH SavingAccountGraph
  NODE TABLES (
    -- The element KEY(account_id) matches the table's primary key.
    SavingAccount KEY(account_id)
  );

Schéma 2 : Utiliser la clause GROUP BY ou SELECT DISTINCT

Dans ce modèle, la requête de la vue utilise une clause GROUP BY ou SELECT DISTINCT. Les colonnes de la clause KEY doivent correspondre à celles que ces clauses utilisent pour définir l'unicité :

  • Pour GROUP BY : les colonnes de la clause KEY doivent correspondre à toutes les colonnes de la clause GROUP BY.

  • Pour SELECT DISTINCT : les colonnes de la clause KEY doivent correspondre aux colonnes de la liste SELECT DISTINCT.

Exemple avec GROUP BY :

CREATE TABLE Customer (
  customer_id INT64,
  name STRING(MAX)
) PRIMARY KEY (customer_id);

CREATE TABLE SaleOrder (
  order_id INT64,
  customer_id INT64,
  amount INT64
) PRIMARY KEY (order_id);

CREATE VIEW CustomerOrder
  SQL SECURITY INVOKER AS
    SELECT
      s.order_id,
      ANY_VALUE(c.customer_id) AS customer_id,
      ANY_VALUE(c.name) AS customer_name
    FROM Customer c JOIN SaleOrder s ON c.customer_id = s.customer_id
    GROUP BY s.order_id;

CREATE PROPERTY GRAPH OrderGraph
  NODE TABLES (
    -- The KEY(order_id) matches the GROUP BY column in view definition.
    CustomerOrder KEY(order_id)
  );

Exemple avec SELECT DISTINCT :

CREATE TABLE SaleOrder (
  order_id INT64,
  customer_id INT64,
  amount INT64
) PRIMARY KEY (order_id);

CREATE VIEW KeyCustomer SQL SECURITY INVOKER AS
  SELECT DISTINCT s.customer_id, s.amount
  FROM SaleOrder s
  WHERE s.amount > 1000;

CREATE PROPERTY GRAPH KeyCustomersGraph
  NODE TABLES (
    -- The KEY(customer_id, amount) matches the DISTINCT columns.
    KeyCustomer KEY(customer_id, amount)
  );

Éléments à prendre en compte lors de l'utilisation de vues

Lorsque vous utilisez des vues pour définir des éléments de graphique, les informations suivantes peuvent vous aider à concevoir et à implémenter un graphique efficace :

Performances des requêtes de graphiques de propriété

Lorsque vous définissez des éléments de graphique sur des vues qui effectuent des transformations de données (par exemple, des opérations GROUP BY, UNNEST ou JOIN), évaluez soigneusement les performances des requêtes pour votre cas d'utilisation. N'oubliez pas que Spanner exécute la définition de requête d'une vue chaque fois qu'une requête effectue une correspondance de modèle d'élément.

Optimisation du schéma de graphique

Lorsque vous utilisez des vues pour définir des éléments de graphique, certaines optimisations du schéma de graphique peuvent être moins efficaces que lorsque vous utilisez des tables pour définir des éléments de graphique.

Vues qui projettent la clé primaire d'une seule table

Si une vue est une projection à partir d'une seule table de base, toutes les optimisations de cette table sous-jacente restent efficaces pour les requêtes de graphiques. Par exemple, l'application des techniques suivantes aux tables de base offre des avantages similaires en termes de performances pour les éléments de graphique définis sur ces vues :

Vues définies avec une clause GROUP BY ou DISTINCT

Les vues qui effectuent des agrégations, telles que GROUP BY, SELECT DISTINCT ou d'autres transformations complexes, perdent la relation directe avec la structure de table sous-jacente. Par conséquent, les optimisations de schéma sur les tables de base peuvent ne pas offrir les mêmes avantages en termes de performances pour les requêtes de graphiques qui fonctionnent sur les vues. Évaluez attentivement les performances des requêtes pour votre cas d'utilisation lorsque vos vues effectuent des agrégations complexes.

Modification des données avec des graphiques basés sur des vues

Les vues ne sont pas matérialisées, ce qui signifie qu'elles ne stockent pas les résultats de la requête qui définit la vue en tant que table dans le stockage de données. Elles sont également en lecture seule. Par conséquent, pour insérer, mettre à jour ou supprimer des nœuds ou des arêtes dans un graphique créé à partir de vues, vous devez modifier les données des tables utilisées pour créer les vues.

Gestion des exceptions de graphique pour garantir l'intégrité des données

Lorsque vous utilisez des vues pour définir des éléments de graphique, appliquez l'intégrité des données (par exemple, appliquez des types de données) sur les tables de base sous-jacentes. Sinon, les données des tables de base peuvent être non valides et entraîner l'échec des requêtes sur votre graphique basé sur les vues lors de l'exécution.

Par exemple, lorsque vous passez d'un graphique sans schéma à un graphique formalisé, utilisez des contraintes CHECK pour valider les données de vos tables de base (GraphNode et GraphEdge). Le code suivant applique ces contraintes dans les propriétés JSON pour garantir l'intégrité des données à la source et éviter les erreurs d'exécution des requêtes.

-- Enforce that the 'name' property exists for nodes with the 'person' label.
ALTER TABLE GraphNode
ADD CONSTRAINT NameMustExistForPersonConstraint
CHECK (IF(label = 'person', properties.name IS NOT NULL, TRUE));

-- Enforce that the 'name' property is a string for nodes with the 'person' label.
ALTER TABLE GraphNode
ADD CONSTRAINT PersonNameMustBeStringTypeConstraint
CHECK (IF(label = 'person', JSON_TYPE(properties.name) = 'string', TRUE));

Étapes suivantes