Créer un graphique à partir d'une vue SQL

Découvrez comment créer un graphique à l'aide de vues SQL. Ce document fournit des instructions détaillées et des exemples de code pour définir des vues et les utiliser afin de définir des tables de nœuds et d'arêtes. Explore exemples avec des exemples de code qui illustrent des cas d'utilisation pour la création de graphiques avec des vues. Pour en savoir plus sur l'utilisation des vues pour créer un graphique de propriété, y compris les avantages et les considérations, consultez la présentation des graphiques créés à partir de vues SQL.

Avant de commencer

Pour créer un graphique, vous devez :

  1. vous assurer que votre environnement Spanner Graph est configuré.

  2. vous familiariser avec le fonctionnement des schémas Spanner Graph.

Créer un graphique à l'aide de vues

Pour créer un graphique à l'aide de vues :

  1. Définissez des vues pour votre graphique. Par défaut, vos vues doivent suivre l'un des modèles de vue compatibles pour garantir l'unicité des éléments. Si vos vues utilisent des requêtes qui ne suivent pas ces modèles, vous pouvez désactiver la validation de l'unicité des clés à l'étape 4. Pour en savoir plus, consultez la section Créer une vue.

  2. Utilisez vos vues dans les NODE TABLES et EDGE TABLES clauses de l' CREATE PROPERTY GRAPH instruction pour créer un graphique.

  3. Incluez la clause KEY dans l'instruction CREATE PROPERTY GRAPH. La clause KEY spécifie les colonnes de la vue source qui identifient de manière unique chaque élément de graphique.

  4. Facultatif : Si vos vues utilisent des requêtes SQL arbitraires qui ne suivent pas les modèles d'unicité compatibles, ajoutez la clause OPTIONS (validate_element_key_uniqueness = false) à l'instruction CREATE PROPERTY GRAPH. Assurez-vous que les colonnes de la clause KEY produisent des valeurs uniques pour chaque ligne de nœud ou d'arête :

    CREATE PROPERTY GRAPH MyGraph
      NODE TABLES (
        CustomerViewTrusted KEY(id)
      ) OPTIONS (validate_element_key_uniqueness = false);
    

    Pour en savoir plus, consultez la section Validation des clés désactivée (n'importe quelle requête SQL).

Exemple : Créer un graphique à l'aide de vues

Cet exemple crée les vues suivantes sur les tables Customer et Account : AsiaCustomer, AsiaBankAccount et AsiaAccountsOwnership. L'exemple utilise ensuite ces vues pour créer les éléments suivants dans un graphique :

  • Créez la table de nœuds Customer à l'aide de la vue AsiaCustomer.

  • Créez la table de nœuds Account à l'aide de la vue AsiaBankAccount.

  • Créez la table d'arêtes Owns à l'aide de la vue AsiaAccountsOwnership. Cette arête connecte les nœuds Customer aux nœuds Account.

Étape 1 : Créer les tables

Commencez par créer les tables de données. Le code suivant crée les tables Customer et Account.

CREATE TABLE Customer (
  customer_id INT64 NOT NULL,
  name STRING(MAX),
  address_continent STRING(MAX),
  address_country STRING(MAX),
) PRIMARY KEY(customer_id);

CREATE TABLE Account (
  account_id INT64 NOT NULL,
  customer_id INT64 NOT NULL,
  account_type STRING(MAX),
  balance INT64,
  create_time TIMESTAMP,
  address_continent STRING(MAX),
  address_country STRING(MAX),
  CONSTRAINT FK_CustomerId FOREIGN KEY (customer_id)
    REFERENCES Customer (customer_id)
) PRIMARY KEY(account_id);

Étape 2 : Créer les vues

Ensuite, créez des vues pour transformer ou filtrer les données des tables. Ces vues filtrent les tables pour n'inclure que les clients et les comptes en Asie. Sauf si validate_element_key_uniqueness est défini sur false, les vues utilisées pour créer des éléments de graphique doivent suivre des modèles compatibles afin de garantir que les lignes de la vue sont uniques.

-- View for 'Customer' nodes, filtered for Asia
CREATE VIEW AsiaCustomer
  SQL SECURITY INVOKER AS
    SELECT customer.customer_id, customer.name
    FROM Customer customer
    WHERE LOWER(customer.address_continent) = "asia";

-- View for 'Account' nodes, filtered for Asia.
CREATE VIEW AsiaBankAccount
  SQL SECURITY INVOKER AS
    SELECT account.account_id, account.balance, account.account_type, account.create_time
    FROM Account account
    WHERE LOWER(account.address_continent) = "asia";

-- View for 'Owns' edges, connecting customers to accounts in Asia.
CREATE VIEW AsiaAccountsOwnership
  SQL SECURITY INVOKER AS
    SELECT account.customer_id, account.account_id
    FROM Account account
    WHERE LOWER(account.address_continent) = "asia";

Étape 3 : Créer le graphique de propriété

Créez maintenant le graphique AsiaFinGraph à l'aide des vues que vous avez créées. L'instruction CREATE PROPERTY GRAPH inclut la clause KEY pour chaque définition d'élément de graphique afin de spécifier les colonnes qui identifient de manière unique les éléments de graphique.

CREATE PROPERTY GRAPH AsiaFinGraph
  NODE TABLES (
    AsiaCustomer AS Customer KEY(customer_id),
    AsiaBankAccount AS Account KEY(account_id)
  )
  EDGE TABLES (
    AsiaAccountsOwnership AS Owns
      KEY(customer_id, account_id)
      SOURCE KEY (customer_id) REFERENCES Customer (customer_id)
      DESTINATION KEY (account_id) REFERENCES Account (account_id)
  );

Exemples de cas d'utilisation

Les vues SQL offrent des avantages par rapport à l'utilisation de tables pour les éléments de graphique de propriété. Les exemples suivants illustrent certains cas d'utilisation pour la définition d'éléments de graphique avec des vues au lieu de tables.

Exemple : Appliquer un contrôle précis des accès aux données de graphique

Pour appliquer la sécurité au niveau des lignes à vos données de graphique, définissez vos tables de nœuds ou d'arêtes à l'aide de vues de droits du définisseur. La vue expose un sous-ensemble autorisé des données sous-jacentes au graphique.

Par exemple, pour limiter l'accès au graphique aux employés d'un centre de coûts d'ingénierie, vous pouvez créer une vue EngineerEmployeeView et accorder des autorisations SELECT sur la vue à un rôle engineering_data_reader à l'aide de la clause GRANT.

Lorsque vous définissez une table de nœuds de graphique à l'aide de cette vue, les utilisateurs exécutant des requêtes de graphique avec le rôle engineering_data_reader ne peuvent voir que les lignes filtrées par la vue, qui incluent les employés d'ingénierie.

-- The table containing all employee data.
CREATE TABLE Employee (
  id INT64 NOT NULL,
  cost_center STRING(MAX),
  job_title STRING(MAX),
  office STRING(MAX)
) PRIMARY KEY (id);

-- The definer's rights view that filters for engineering employees.
CREATE VIEW EngineerEmployeeView SQL SECURITY DEFINER AS
  SELECT e.id, e.cost_center, e.job_title, e.office
  FROM Employee e
  WHERE LOWER(e.cost_center) = "engineering";

-- The role that is granted to read the view.
CREATE ROLE engineering_data_reader;
GRANT SELECT ON VIEW EngineerEmployeeView TO ROLE engineering_data_reader;

-- The graph that uses definer's rights view.
CREATE PROPERTY GRAPH EngineeringGraph
  NODE TABLES (
    EngineerEmployeeView KEY(id)
  );

Exemple : Modéliser des éléments de graphique dérivés

Vous pouvez utiliser des vues pour définir des éléments de graphique qui nécessitent des transformations de données. L'avantage principal est que la vue définit la transformation. Vous n'avez donc pas besoin de gérer une table distincte pour les données dérivées.

Par exemple, vous pouvez UNNEST des données d'une colonne ARRAY (ou d'un champ de tableau dans une colonne JSON) pour modéliser plusieurs relations d'arêtes à partir d'une seule ligne.

Dans l'exemple de schéma de chaîne d'approvisionnement suivant, une table Parts stocke une liste de sous-composants dans un tableau dependent_parts. Une vue peut utiliser l'opérateur UNNEST pour transformer chaque élément de ce tableau en lignes distinctes. Cette vue peut ensuite servir de table d'arêtes, ce qui vous permet de modéliser une arête PartDependsOnPart pour représenter les relations de dépendance entre les pièces.

-- Parts table with an ARRAY of dependent parts.
CREATE TABLE Parts (
  part_id INT64 NOT NULL,
  dependent_parts ARRAY<INT64>
) PRIMARY KEY (part_id);

-- A view that unnests the dependent_parts array.
-- GROUP BY ensures uniqueness for the graph element KEY.
CREATE VIEW PartDependsOnPart SQL SECURITY INVOKER AS
  SELECT p.part_id, dependent_part_id
  FROM Parts AS p,
    UNNEST(p.dependent_parts) AS dependent_part_id
  GROUP BY p.part_id, dependent_part_id;

-- Graph modeling the part dependency relationship.
CREATE PROPERTY GRAPH SupplyChainGraph
  NODE TABLES (
    Parts
  )
  EDGE TABLES (
    PartDependsOnPart KEY (part_id, dependent_part_id)
      SOURCE KEY (part_id) REFERENCES Parts(part_id)
      DESTINATION KEY (dependent_part_id) REFERENCES Parts(part_id)
  );

Exemple : Transition de données sans schéma

La gestion des données sans schéma vous permet de créer une définition de graphique flexible sans types de nœuds ni d'arêtes prédéfinis. Bien que la gestion des données sans schéma offre une certaine flexibilité, vous devrez peut-être passer à une structure plus formelle à mesure que vos données deviennent plus définies. Une structure plus formelle expose les relations, les libellés et les propriétés des nœuds et des arêtes du graphique dans le schéma, ce qui réduit le besoin d'exploration manuelle des données pour comprendre le schéma du graphique.

Vous pouvez utiliser des vues pour formaliser les types de nœuds et d'arêtes sans migrer vos données sous-jacentes. Par exemple, vous pouvez passer d'un modèle sans schéma typique qui utilise des tables GraphNode et GraphEdge canoniques. Pour ce faire, créez des vues qui extraient les données de vos tables sans schéma :

  1. Définissez une vue pour chaque type de nœud et d'arête que vous souhaitez formaliser (par exemple, Person ou WorksFor). Dans la vue, filtrez les données par leur libellé (par exemple, WHERE n_label = "person") et convertissez les propriétés de la colonne JSON en types de données spécifiques (par exemple, STRING(prop.name) AS name).

  2. Définissez un nouveau graphique de propriété où NODE TABLES et EDGE TABLES font référence aux vues typées que vous venez de créer.

Un graphique sans schéma offre de meilleures performances qu'un graphique formalisé pour certaines requêtes (par exemple, un modèle de chemin quantifié avec plusieurs types d'arêtes). Si les métadonnées formalisées sont importantes pour votre cas d'utilisation, vous pouvez utiliser des vues pour passer d'un graphique sans schéma à un schéma typé. Vous pouvez également choisir d'utiliser un graphique sans schéma pour certains cas d'utilisation et un graphique de schéma typé pour d'autres. Pour en savoir plus, consultez la section Choisir une conception de schéma en fonction des requêtes de graphique.

L'exemple suivant illustre le workflow de transition d'un graphique sans schéma à un graphique formalisé en quatre étapes :

  1. Définissez les tables GraphNode et GraphEdge canoniques pour le modèle sans schéma.

  2. Créez un graphique initial et flexible sur ces tables sans schéma.

  3. Définissez des vues typées (Person, Company, WorksFor) qui extraient et formalisent les données des tables sans schéma.

  4. Créez le graphique final fortement typé qui utilise ces vues comme tables de nœuds et d'arêtes.

-- 1. Create the canonical tables for a schemaless model.
CREATE TABLE GraphNode (
  id INT64 NOT NULL,
  label STRING(MAX) NOT NULL,
  properties JSON
) PRIMARY KEY (id);

CREATE TABLE GraphEdge (
  id INT64 NOT NULL,
  dest_id INT64 NOT NULL,
  edge_id INT64 NOT NULL,
  label STRING(MAX) NOT NULL,
  properties JSON
) PRIMARY KEY (id, dest_id, edge_id),
  INTERLEAVE IN PARENT GraphNode;

-- 2. Define a schemaless graph.
CREATE PROPERTY GRAPH FinGraph
  NODE TABLES (
    GraphNode
      DYNAMIC LABEL (label)
      DYNAMIC PROPERTIES (properties)
  )
  EDGE TABLES (
    GraphEdge
      SOURCE KEY (id) REFERENCES GraphNode(id)
      DESTINATION KEY (dest_id) REFERENCES GraphNode(id)
      DYNAMIC LABEL (label)
      DYNAMIC PROPERTIES (properties)
  );

-- 3. Define typed views that extract and formalize the data.
--    Convert JSON fields to primitive types (for example, INT64, STRING) to
--    ensure type safety.
CREATE VIEW Person SQL SECURITY INVOKER AS
  SELECT n.id, STRING(n.properties.name) AS name, INT64(n.properties.age) AS age
  FROM GraphNode n WHERE n.label = "person";

CREATE VIEW Company SQL SECURITY INVOKER AS
  SELECT n.id, STRING(n.properties.name) AS company_name, BOOL(n.properties.is_public) AS is_public
  FROM GraphNode n WHERE n.label = "company";

CREATE VIEW WorksFor SQL SECURITY INVOKER AS
  SELECT e.id AS person_id, e.dest_id AS company_id, e.edge_id AS edge_id, STRING(e.properties.since) AS since
  FROM GraphEdge e
  WHERE e.label = "worksfor";

-- 4. Create the final, formalized graph from the typed views.
CREATE PROPERTY GRAPH typed_formalized_graph
  NODE TABLES (
    Person KEY(id)
      PROPERTIES (name, age),
    Company KEY(id)
      PROPERTIES (company_name, is_public)
  )
  EDGE TABLES(
    WorksFor KEY(person_id, company_id, edge_id)
      SOURCE KEY (person_id) REFERENCES Person(id)
      DESTINATION KEY (company_id) REFERENCES Company(id)
      PROPERTIES (since)
  );

Étape suivante