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

Ce document explique les avantages de l'utilisation de vues SQL pour créer un graphique. Il présente 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é à partir de vues SQL.

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

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 qui fait 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 qui définit 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 graphique qui ne sont pas disponibles lorsque vous utilisez des tables pour créer un graphique.

Exigences 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 KEY clause lors de la création d'un élément de graphique, consultez les exemples de code de ce document et de Créer un Spanner Graph à partir d'une vue SQL.

S'assurer que les clés de nœud et d'arête sont uniques

Chaque nœud et chaque arête d'un graphique de propriété doit avoir une clé unique. Lorsque vous définissez des éléments de graphique à l'aide de vues, vous pouvez choisir comment vérifier l'unicité des clés d'élément :

Validation stricte des clés (par défaut)

Par défaut, Spanner vérifie que les vues qui définissent des tables de nœuds ou d'arêtes suivent l'un des modèles suivants pour s'assurer que chaque nœud ou arête est unique :

  • Modèle 1 : la vue utilise la clé primaire d'une seule table.

  • Modèle 2 : la vue utilise une GROUP BY ou une SELECT DISTINCT clause.

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 ils ne modifient pas la garantie d'unicité sous-jacente fournie par les modèles.

Modèle 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)
  );

Modèle 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 aux colonnes 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)
  );

Validation des clés désactivée (n'importe quelle requête SQL)

Si votre vue utilise une requête qui ne suit pas le modèle 1 ou le modèle 2 (par exemple, une requête qui joint des tables sans clause GROUP BY ni SELECT DISTINCT), vous pouvez désactiver la validation des clés d'élément en définissant l'option de graphique validate_element_key_uniqueness = false.

Par défaut, validate_element_key_uniqueness est défini sur true. Lorsque cette option est définie sur false, Spanner ne valide pas la définition de requête de la vue au moment de la création du schéma. Vous pouvez utiliser n'importe quelle requête SQL dans la vue, mais vous devez vous assurer que les colonnes spécifiées dans la clause KEY contiennent des valeurs uniques pour chaque ligne de nœud ou d'arête.

L'exemple suivant définit une vue nommée CustomerOrderTrusted qui joint les Customer et SaleOrder tables sans clause GROUP BY. Étant donné que chaque ordre de vente est unique, la jointure de SaleOrder avec Customer préserve l'unicité de order_id dans les résultats de la vue. Toutefois, comme la requête utilise une JOIN et ne suit pas le modèle 1 ni le modèle 2, Spanner ne peut pas vérifier l'unicité de manière syntaxique.

En spécifiant KEY(order_id) et en définissant validate_element_key_uniqueness = false dans la clause OPTIONS, vous pouvez définir le graphique de propriété sans modifier la requête de la vue :

-- View uses a JOIN without GROUP BY or DISTINCT.
CREATE VIEW CustomerOrderTrusted
  SQL SECURITY INVOKER AS
    SELECT
      s.order_id,
      c.customer_id,
      c.name AS customer_name
    FROM Customer c JOIN SaleOrder s ON c.customer_id = s.customer_id;

-- Property graph disables element key uniqueness validation.
CREATE PROPERTY GRAPH OrderGraphTrusted
  NODE TABLES (
    CustomerOrderTrusted
      KEY(order_id)
      LABEL CustomerOrder PROPERTIES(
        order_id,
        customer_id,
        customer_name)
  ) OPTIONS (validate_element_key_uniqueness = false);

Points à prendre en compte lors de l'utilisation de vues

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

Performances des requêtes de graphique 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 de 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 graphique. 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 la 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 graphique qui fonctionnent sur les vues. Évaluez soigneusement 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, et qu'elles sont 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 appliquer 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 des vues au moment 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 de requête au moment de l'exécution.

-- 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));

Étape suivante