Ce document vous explique les avantages d'utiliser des vues SQL pour créer un graphe. Ce document 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 graphe à partir de vues, consultez Créer un graphe de propriétés à 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 définissant 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 graphe à partir de vues SQL, mais vous ne pouvez pas créer de vue qui interroge un graphe.
Les vues offrent plusieurs avantages en tant que couche d'abstraction entre les tables et un schéma de graphe qui ne sont pas disponibles lorsque vous utilisez des tables pour créer un graphe.
Contrôle des accès au niveau des lignes. Appliquez un contrôle ultraprécis des accès au niveau des lignes aux données du graphe à l'aide des droits de sécurité des vues de droits du définisseur. Cela garantit que les utilisateurs ne peuvent interroger que les nœuds et les arêtes qu'ils sont autorisés à voir.
Modélisation flexible des données. Utilisez une vue avec une requête pour mettre en forme et transformer des données relationnelles avant de créer un élément de graphe. La requête de la vue vous permet de filtrer les lignes, de combiner des colonnes, d'annuler l'imbrication de champs répétés (comme dans un
ARRAY) ou de calculer des propriétés à l'aide de fonctions distantes.Passer de données sans schéma à des données formalisées. Créez des vues à partir de données sans schéma pour définir explicitement les types de nœuds et d'arêtes. Cela permet de formaliser les relations dans les données.
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 :
Utilisez la clause
KEYlorsque vous spécifiez un élément de graphique.Activez les colonnes volatiles lorsque les vues utilisent des fonctions distantes.
Utiliser la clause KEY lorsque vous spécifiez un élément de graphe
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 graphe, consultez les exemples de code de ce document et de la section Créer un Spanner Graph à partir d'une vue SQL.
Assurer l'unicité des clés de nœud et d'arête
Chaque nœud et chaque arête d'un graphique de propriétés doivent avoir une clé unique. Lorsque vous définissez des éléments de graphique à l'aide de vues, vous pouvez choisir comment l'unicité des clés d'élément est vérifiée :
- Validation stricte des clés (par défaut) : Spanner vérifie que les vues suivent les schémas de requête compatibles pour garantir l'unicité des clés.
- Validation de clé désactivée (toute requête SQL) : vous pouvez utiliser n'importe quelle requête SQL si vous définissez l'option de graphique
validate_element_key_uniqueness = false. Dans ce mode, vous devez vous assurer que les clés d'élément sont uniques.
Validation stricte des clés (par défaut)
Par défaut, Spanner vérifie que les vues définissant 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 clause
GROUP BYouSELECT 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 ordonnent les résultats, mais 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 sélectionne 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 une 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 clauseKEYdoivent correspondre à toutes les colonnes de la clauseGROUP BY.Pour
SELECT DISTINCT: les colonnes de la clauseKEYdoivent correspondre aux colonnes de la listeSELECT 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 de clé désactivée (toute 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 ou SELECT DISTINCT), vous pouvez désactiver la validation de la clé d'élément en définissant l'option de graphique validate_element_key_uniqueness = false.
La valeur par défaut de validate_element_key_uniqueness est true. Lorsqu'elle est définie sur false, Spanner ne valide pas la définition de la 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 tables Customer et SaleOrder sans clause GROUP BY. Étant donné que chaque commande 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 un JOIN et ne suit pas le modèle 1 ou 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 graphe de propriétés sans modifier la requête de 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);
Activer les colonnes volatiles lorsque les vues utilisent des fonctions distantes
Vous pouvez définir un graphique de propriétés sur une vue qui appelle une fonction distante (LANGUAGE REMOTE) en définissant allow_view_with_volatile_column = true dans la clause OPTIONS de l'instruction CREATE PROPERTY GRAPH.
Par défaut, Spanner ne vous permet pas de définir un graphe de propriétés sur des vues avec des colonnes volatiles (allow_view_with_volatile_column = false). Une colonne de vue est volatile si son expression appelle une fonction volatile. Une fonction est volatile si sa valeur de retour peut changer même au cours d'une seule exécution d'instruction avec les mêmes arguments, comme une fonction distante (NOT DETERMINISTIC). Toute volatilité dans le corps de définition d'une vue, par exemple dans une condition JOIN ou une clause WHERE, rend également volatiles toutes les colonnes projetées de la vue. Pour obtenir un exemple de code, consultez Calculer des propriétés avec des fonctions distantes.
É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 é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 mise en correspondance de modèles d'éléments.
Optimisation du schéma de graphe
Lorsque vous utilisez des vues pour définir des éléments de graphe, certaines optimisations de schéma de graphe peuvent être moins efficaces que lorsque vous utilisez des tables pour définir des éléments de graphe.
Vues qui projettent la clé primaire d'une seule table
Si une vue est une projection d'une seule table de base, toutes les optimisations de cette table sous-jacente restent effectives pour les requêtes de graphe. Par exemple, l'application des techniques suivantes aux tables de base offre des avantages de performances similaires pour les éléments de graphe 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 graphe qui s'exécutent 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 graphe créé à partir de vues, vous devez modifier les données des tables utilisées pour créer les vues.
Gestion des exceptions de graphe pour assurer l'intégrité des données
Lorsque vous utilisez des vues pour définir des éléments de graphe, 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 risquent de ne pas être valides et d'entraîner l'échec des requêtes sur votre graphique basé sur une vue au moment de l'exécution.
Par exemple, lorsque vous passez d'un graphe sans schéma à un graphe 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 d'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));
Étapes suivantes
Découvrez comment créer un graphique de propriétés à partir de vues SQL.
Découvrez le schéma Spanner Graph.
Découvrez les bonnes pratiques pour concevoir un schéma Spanner Graph.