Scopri come creare un grafo utilizzando le viste SQL. Questo documento fornisce istruzioni passo passo ed esempi di codice per definire le viste e utilizzarle per definire le tabelle di nodi e archi. Esplora gli esempi con codice campione che mostrano i casi d'uso per la creazione di grafici con visualizzazioni. Per scoprire di più sull'utilizzo delle viste per creare un grafo delle proprietà, inclusi vantaggi e considerazioni, consulta Panoramica dei grafi creati dalle viste SQL.
Prima di iniziare
Per creare un grafico, devi:
Assicurati che l'ambiente Spanner Graph sia configurato.
Acquisisci familiarità con il funzionamento degli schemi di Spanner Graph.
Crea un grafo utilizzando le visualizzazioni
Per creare un grafico utilizzando le visualizzazioni:
Definisci le visualizzazioni per il grafico. Per impostazione predefinita, le visualizzazioni devono seguire uno dei pattern di visualizzazione supportati per garantire l'unicità degli elementi. Se le visualizzazioni utilizzano query che non seguono questi pattern, puoi disattivare la convalida dell'unicità della chiave nel passaggio 4. Per saperne di più, consulta Crea una visualizzazione.
Utilizza le visualizzazioni nelle clausole
NODE TABLESeEDGE TABLESdell'istruzioneCREATE PROPERTY GRAPHper creare un grafico.Includi la clausola
KEYnell'istruzioneCREATE PROPERTY GRAPH. La clausolaKEYspecifica le colonne della vista di origine che identificano in modo univoco ogni elemento del grafico.(Facoltativo) Se le tue visualizzazioni utilizzano query SQL arbitrarie che non seguono i pattern di unicità supportati, aggiungi la clausola
OPTIONS (validate_element_key_uniqueness = false)all'istruzioneCREATE PROPERTY GRAPH. Assicurati che le colonne della clausolaKEYproducano 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 della chiave disabilitata (qualsiasi query SQL).
(Facoltativo) Se le tue viste chiamano una funzione remota o hanno altre colonne volatili, aggiungi la clausola
OPTIONS (allow_view_with_volatile_column = true)all'istruzioneCREATE PROPERTY GRAPH:CREATE PROPERTY GRAPH MyGraph NODE TABLES ( AccountRemoteUdfView KEY(account_id) ) OPTIONS (allow_view_with_volatile_column = true);Per saperne di più, consulta Abilita le colonne volatili quando le viste utilizzano funzioni remote.
Esempio: crea 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
Customerutilizzando la vistaAsiaCustomer.Crea la tabella dei nodi
Accountutilizzando la vistaAsiaBankAccount.Crea la tabella degli archi
Ownsutilizzando la vistaAsiaAccountsOwnership. Questo arco collega i nodiCustomercon i nodiAccount.
Passaggio 1: crea le tabelle
Innanzitutto, crea le tabelle di dati. Il codice seguente 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
Successivamente, crea viste per trasformare o filtrare i dati delle tabelle. Queste viste filtrano le tabelle in modo da includere solo i clienti e gli 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 nella 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 il 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 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 visualizzazioni anziché tabelle.
Esempio: applica controllo dell'accesso ai dati dei grafici granulare
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 al grafico un sottoinsieme consentito dei dati sottostanti
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 grafo utilizzando questa vista, gli utenti che eseguono query sul grafo con il ruolo engineering_data_reader possono visualizzare solo le righe filtrate dalla vista, che includono i dipendenti del team 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: elementi del grafo derivati dal modello
Puoi utilizzare le visualizzazioni per definire gli elementi del grafico che richiedono trasformazioni dei dati. Un vantaggio fondamentale è che la vista definisce la trasformazione, quindi non è necessario mantenere una tabella separata per i dati derivati.
Unnest degli array per modellare gli archi
Ad esempio, puoi UNNEST i dati da una colonna ARRAY (o un campo array all'interno di una colonna JSON) per modellare più relazioni di archi da una singola riga.
Nell'esempio di schema della catena di fornitura riportato di seguito, 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 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)
);
Calcola le proprietà con le funzioni remote
Puoi anche utilizzare una funzione remota in una vista per calcolare le proprietà derivate per gli elementi del grafico impostando allow_view_with_volatile_column = true nella clausola OPTIONS dell'istruzione CREATE
PROPERTY GRAPH. Per saperne di più, consulta Abilita le colonne volatili quando le viste utilizzano funzioni remote.
-- Define a remote function.
CREATE FUNCTION rudf_identity_func(x INT64)
RETURNS INT64 NOT DETERMINISTIC LANGUAGE REMOTE
OPTIONS (
endpoint = 'https://us-central1-project-id.cloudfunctions.net/my-func'
);
-- Base table for accounts.
CREATE TABLE Account (
account_id INT64 NOT NULL,
balance INT64
) PRIMARY KEY (account_id);
-- View that computes a property using the remote function.
CREATE VIEW AccountRemoteUdfView SQL SECURITY INVOKER AS
SELECT
t.account_id,
t.balance,
rudf_identity_func(t.account_id) AS view_computed_prop
FROM Account AS t;
-- Graph using the view requires allow_view_with_volatile_column = true.
CREATE PROPERTY GRAPH AccountViewRemoteUdfGraph
NODE TABLES (
AccountRemoteUdfView KEY (account_id)
PROPERTIES (account_id, balance, view_computed_prop)
)
OPTIONS (allow_view_with_volatile_column = true);
Esempio: transizione dei dati senza schema
La gestione dei dati senza schema consente di creare una definizione di grafo 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 grafo nello schema, riducendo la necessità di esplorare manualmente i dati per comprendere lo schema del grafo.
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 tabelle GraphNode e GraphEdge canoniche. Per farlo, crea viste che estraggono i dati dalle tabelle senza schema:
Definisci una vista per ogni tipo di nodo e arco che vuoi formalizzare (ad esempio
PersonoWorksFor). Nella vista, filtra i dati in base alla relativa etichetta (ad esempioWHERE n_label = "person") ed esegui il cast delle proprietà dalla colonna JSON a tipi di dati specifici (ad esempioSTRING(prop.name) AS name).Definisci un nuovo grafico delle proprietà in cui
NODE TABLESeEDGE TABLESfanno riferimento alle viste tipizzate appena create.
Un grafo senza schema offre prestazioni migliori rispetto a un grafo 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 grafo senza schema a uno schema con tipo. Puoi anche scegliere di utilizzare un grafo senza schema per alcuni casi d'uso e un grafo con schema tipizzato per altri. Per saperne di più, consulta Scegli un design dello schema basato sulle query del grafico.
L'esempio seguente mostra il flusso di lavoro per la transizione da un grafo senza schema a un grafo formalizzato in quattro passaggi:
Definisci le tabelle canoniche
GraphNodeeGraphEdgeper il modello senza schema.Crea un grafo iniziale flessibile su queste tabelle senza schema.
Definisci viste tipizzate (
Person,Company,WorksFor) che estraggono e formalizzano i dati dalle tabelle senza schema.Crea il grafico finale con tipizzazione forte che utilizza queste viste come tabelle di nodi e 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
Scopri di più sui requisiti di unicità delle chiavi degli elementi.
Scopri di più sullo schema Spanner Graph.
Scopri le best practice per la progettazione di uno schema Spanner Graph.