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 le tabelle dei nodi e degli archi. Esplora esempi con codice campione che illustrano i casi d'uso per la creazione di grafici con le viste. Per saperne di più sull'utilizzo delle viste per creare un grafico delle proprietà, inclusi vantaggi e considerazioni, consulta Panoramica dei grafici creati da viste SQL.

Prima di iniziare

Per creare un grafico, devi:

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

  2. Acquisire familiarità con il funzionamento degli schemi di Spanner Graph.

Creare un grafico utilizzando le viste

Per creare un grafico utilizzando le viste:

  1. Definisci le viste per il grafico. Per impostazione predefinita, le viste devono seguire uno dei pattern di visualizzazione supportati per garantire l'unicità degli elementi. Se le viste utilizzano query che non seguono questi pattern, puoi disattivare la convalida dell'unicità delle chiavi nel passaggio 4. Per saperne di più, consulta Creare una vista.

  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 nell'istruzione CREATE PROPERTY GRAPH. La clausola KEY specifica le colonne della vista di origine che identificano in modo univoco ogni elemento del grafico.

  4. (Facoltativo) Se le viste utilizzano query SQL arbitrarie che non seguono i pattern di unicità supportati, aggiungi la clausola OPTIONS (validate_element_key_uniqueness = false) all'istruzione CREATE PROPERTY GRAPH. Assicurati che le colonne della clausola KEY producano valori univoci per ogni riga di nodo o arco:

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

    Per saperne di più, consulta Convalida delle chiavi disattivata (qualsiasi query SQL).

Esempio: creare un grafico utilizzando le viste

Questo esempio crea le seguenti viste sulle tabelle Customer e Account: AsiaCustomer, AsiaBankAccount e AsiaAccountsOwnership. Poi, l'esempio utilizza queste viste 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 i nodi Customer ai nodi Account.

Passaggio 1: crea le tabelle

Per prima cosa, crea le tabelle dei 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 viste

Poi, crea le viste per trasformare o filtrare i dati delle tabelle. Queste viste filtrano le tabelle in modo da includere solo clienti e account in Asia. A meno che validate_element_key_uniqueness non sia impostato su false, le viste utilizzate per creare gli elementi del grafico devono seguire i pattern supportati per garantire che le righe della vista siano univoche.

-- 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 AsiaFinGraph utilizzando le viste 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 delle tabelle per gli elementi del grafico delle proprietà. Gli esempi seguenti illustrano alcuni casi d'uso per la definizione di elementi del grafico con le viste anziché con le tabelle.

Esempio: applicare un 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 degli archi 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 sui grafici con il ruolo engineering_data_reader possono visualizzare solo le righe filtrate dalla vista, che includono i dipendenti di ingegneria.

-- 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: modellare gli elementi del grafico derivati

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 è necessario 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 di archi da una singola riga.

Nel seguente esempio di schema della catena di fornitura, una tabella Parts memorizza un elenco di sottocomponenti in un array dependent_parts. Una vista può utilizzare l'operatore UNNEST per trasformare ogni elemento di questo array in righe distinte. Questa vista può quindi fungere da tabella degli archi, consentendoti di modellare un arco 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 consente di creare una definizione di grafico flessibile senza tipi di nodi e archi predefiniti. Sebbene la gestione dei dati senza schema offra flessibilità, potrebbe essere necessario passare a una struttura più formale man mano che i dati diventano più definiti. Una struttura più formale espone le relazioni, le etichette e le proprietà dei nodi e degli archi del grafico nello schema, il che riduce la necessità di esplorare manualmente i dati per comprendere lo schema del grafico.

Puoi utilizzare le viste per formalizzare i tipi di nodi e archi senza eseguire la migrazione dei dati sottostanti. Ad esempio, puoi eseguire la transizione da un modello senza schema tipico che utilizza le tabelle canoniche GraphNode e GraphEdge. Per farlo, crea le 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") ed esegui il cast delle proprietà dalla colonna JSON a 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 con tipo 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 viste per eseguire la transizione da un grafico senza schema a uno schema con tipo. Puoi anche scegliere di utilizzare un grafico senza schema per alcuni casi d'uso e un grafico con schema con tipo per altri casi d'uso. Per saperne di più, consulta Scegliere una progettazione dello schema in base alle query sui grafici.

L'esempio seguente illustra 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 e flessibile su queste tabelle senza schema.

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

  4. Crea il grafico finale con tipo che utilizza queste viste come tabelle dei nodi e degli archi.

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