Crea un grafico da una vista SQL

Scopri come creare un grafico utilizzando le viste SQL. Questo documento fornisce istruzioni passo passo ed esempi di codice per definire le viste e utilizzarle per definire tabelle di nodi e archi. Esplora gli esempi con codice campione che mostrano i casi d'uso per la creazione di grafici con viste. Per scoprire di più sull'utilizzo delle viste per creare un grafico delle proprietà, inclusi vantaggi e considerazioni, consulta Panoramica dei grafici creati dalle viste SQL.

Prima di iniziare

Per creare un grafico, devi:

  1. Assicurati che l'ambiente Spanner Graph sia configurato.

  2. Familiarizza con il funzionamento degli schemi Spanner Graph.

Creare un grafico utilizzando le visualizzazioni

Per creare un grafico utilizzando le visualizzazioni:

  1. Definisci le visualizzazioni per il grafico. Assicurati che le visualizzazioni seguano uno dei pattern di visualizzazione richiesti. Per saperne di più, vedi Creare una visualizzazione.

  2. Utilizza le viste nelle clausole NODE TABLES e EDGE TABLES dell'istruzione CREATE PROPERTY GRAPH per creare un grafico.

  3. Includi la clausola KEY nella dichiarazione CREATE PROPERTY GRAPH. La clausola KEY specifica le colonne della visualizzazione di origine che identificano in modo univoco ogni elemento del grafico.

Esempio: creare un grafico utilizzando le visualizzazioni

Questo esempio crea le seguenti visualizzazioni sulle tabelle Customer e Account: AsiaCustomer, AsiaBankAccount e AsiaAccountsOwnership. Poi, l'esempio utilizza queste visualizzazioni per creare quanto segue in un grafico:

  • Crea la tabella dei nodi Customer utilizzando la vista AsiaCustomer.

  • Crea la tabella dei nodi Account utilizzando la vista AsiaBankAccount.

  • Crea la tabella degli archi Owns utilizzando la vista AsiaAccountsOwnership. Questo arco collega Customer nodi con Account nodi.

Passaggio 1: crea le tabelle

Innanzitutto, crea le tabelle di dati. Il seguente codice crea le tabelle Customer e 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);

Passaggio 2: crea le visualizzazioni

Poi, crea le viste per trasformare o filtrare i dati delle tabelle. Queste visualizzazioni filtrano le tabelle in modo da includere solo clienti e account in Asia. Le visualizzazioni utilizzate per creare gli elementi del grafico devono garantire che le righe della visualizzazione siano uniche.

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

Passaggio 3: crea il grafico delle proprietà

Ora crea il AsiaFinGraph utilizzando le visualizzazioni che hai creato. L'istruzione CREATE PROPERTY GRAPH include la clausola KEY per ogni definizione di elemento del grafico per specificare le colonne che identificano in modo univoco gli elementi del grafico.

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

Esempi di casi d'uso

Le viste SQL offrono vantaggi rispetto all'utilizzo di tabelle per gli elementi del grafico delle proprietà. Gli esempi seguenti mostrano alcuni casi d'uso per la definizione di elementi del grafico con viste anziché tabelle.

Esempio: applicare controllo dell'accesso granulare ai dati del grafico

Per applicare la sicurezza a livello di riga ai dati del grafico, definisci le tabelle dei nodi o dei bordi utilizzando le viste dei diritti del definer. La vista espone un sottoinsieme consentito dei dati sottostanti al grafico

Ad esempio, per limitare l'accesso al grafico solo ai dipendenti di un centro di costo di ingegneria, puoi creare una vista EngineerEmployeeView e concedere le autorizzazioni SELECT sulla vista a un ruolo engineering_data_reader utilizzando la clausola GRANT.

Quando definisci una tabella dei nodi del grafico utilizzando questa vista, gli utenti che eseguono query del grafico con il ruolo engineering_data_reader possono visualizzare solo le righe filtrate dalla vista, che includono i dipendenti del reparto tecnico.

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

Esempio: elementi del grafico derivati dal modello

Puoi utilizzare le viste per definire gli elementi del grafico che richiedono trasformazioni dei dati. Un vantaggio fondamentale è che la vista definisce la trasformazione, quindi non devi gestire una tabella separata per i dati derivati.

Ad esempio, puoi UNNEST i dati da una colonna ARRAY (o da un campo array all'interno di una colonna JSON) per modellare più relazioni tra nodi da una singola riga.

Nel seguente esempio di schema della supply chain, una tabella Parts memorizza un elenco di componenti secondari in un array dependent_parts. Una vista può utilizzare l'operatore UNNEST per trasformare ogni elemento dell'array in righe distinte. Questa visualizzazione può quindi fungere da tabella edge, consentendoti di modellare un edge PartDependsOnPart per rappresentare le relazioni di dipendenza tra le parti.

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

Esempio: transizione dei dati senza schema

La gestione dei dati senza schema ti consente di creare una definizione di grafico flessibile senza tipi di nodi e archi predefiniti. Sebbene la gestione dei dati senza schema offra flessibilità, potresti dover passare a una struttura più formale man mano che i dati diventano più definiti. Una struttura più formale espone le relazioni tra nodi e archi, le etichette e le proprietà del grafico nello schema, il che riduce la necessità di esplorare manualmente i dati per comprendere lo schema del grafico.

Puoi utilizzare le visualizzazioni per formalizzare i tipi di nodi e archi senza eseguire la migrazione dei dati sottostanti. Ad esempio, puoi passare da un tipico modello senza schema che utilizza le tabelle canoniche GraphNode e GraphEdge. Per farlo, crea viste che estraggono i dati dalle tabelle senza schema:

  1. Definisci una vista per ogni tipo di nodo e arco che vuoi formalizzare (ad esempio, Person o WorksFor). Nella vista, filtra i dati in base alla relativa etichetta (ad esempio, WHERE n_label = "person") e converti le proprietà dalla colonna JSON in tipi di dati specifici (ad esempio, STRING(prop.name) AS name).

  2. Definisci un nuovo grafico delle proprietà in cui NODE TABLES e EDGE TABLES fanno riferimento alle viste tipizzate che hai appena creato.

Un grafico senza schema offre prestazioni migliori rispetto a un grafico formalizzato per alcune query (ad esempio, un pattern di percorso quantificato con più tipi di archi). Se i metadati formalizzati sono importanti per il tuo caso d'uso, puoi utilizzare le visualizzazioni per passare da un grafico senza schema a uno schema digitato. Puoi anche scegliere di utilizzare un grafico senza schema per alcuni casi d'uso e un grafico con schema digitato per altri casi d'uso. Per ulteriori informazioni, consulta Scegliere una progettazione dello schema in base alle query del grafico.

L'esempio seguente mostra il flusso di lavoro per la transizione da un grafico senza schema a un grafico formalizzato in quattro passaggi:

  1. Definisci le tabelle canoniche GraphNode e GraphEdge per il modello senza schema.

  2. Crea un grafico iniziale flessibile su queste tabelle senza schema.

  3. Definisci viste tipizzate (Person, Company, WorksFor) che estraggono e formalizzano i dati dalle tabelle senza schema.

  4. Crea il grafico finale fortemente tipizzato che utilizza queste viste come tabelle di nodi e bordi.

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

Passaggi successivi