Aprende a crear un grafo con vistas de SQL. En este documento, se proporcionan instrucciones paso a paso y ejemplos de código para definir vistas y usarlas para definir tablas de nodos y bordes. Explora ejemplos con código de muestra que ilustran casos de uso para crear gráficos con vistas. Para obtener más información sobre el uso de vistas para crear un grafo de propiedades, incluidos los beneficios y las consideraciones, consulta Descripción general de los grafos creados a partir de vistas de SQL.
Antes de comenzar
Para crear un grafo, debes hacer lo siguiente:
Asegúrate de que tu entorno de Spanner Graph esté configurado.
Familiarízate con cómo funcionan los esquemas de Spanner Graph.
Crea un gráfico con vistas
Para crear un gráfico con vistas, haz lo siguiente:
Define vistas para tu gráfico. De forma predeterminada, tus vistas deben seguir uno de los patrones de vista admitidos para garantizar la unicidad de los elementos. Si tus vistas usan consultas que no siguen estos patrones, puedes inhabilitar la validación de unicidad de claves en el paso 4. Para obtener más información, consulta Crea una vista.
Usa tus vistas en las cláusulas
NODE TABLESyEDGE TABLESde la sentenciaCREATE PROPERTY GRAPHpara crear un grafo.Incluye la cláusula
KEYen la sentenciaCREATE PROPERTY GRAPH. La cláusulaKEYespecifica las columnas de la vista de origen que identifican de forma inequívoca cada elemento del grafo.Opcional: Si tus vistas usan consultas en SQL arbitrarias que no siguen los patrones de unicidad admitidos, agrega la cláusula
OPTIONS (validate_element_key_uniqueness = false)a la declaraciónCREATE PROPERTY GRAPH. Asegúrate de que las columnas de la cláusulaKEYproduzcan valores únicos para cada fila de nodo o de borde:CREATE PROPERTY GRAPH MyGraph NODE TABLES ( CustomerViewTrusted KEY(id) ) OPTIONS (validate_element_key_uniqueness = false);Para obtener más información, consulta Validación de claves inhabilitadas (cualquier consulta en SQL).
Opcional: Si tus vistas llaman a una función remota o tienen otras columnas volátiles, agrega la cláusula
OPTIONS (allow_view_with_volatile_column = true)a la sentenciaCREATE PROPERTY GRAPH:CREATE PROPERTY GRAPH MyGraph NODE TABLES ( AccountRemoteUdfView KEY(account_id) ) OPTIONS (allow_view_with_volatile_column = true);Para obtener más información, consulta Habilita columnas volátiles cuando las vistas usen funciones remotas.
Ejemplo: Crea un grafo con vistas
En este ejemplo, se crean las siguientes vistas en las tablas Customer y Account:
AsiaCustomer, AsiaBankAccount y AsiaAccountsOwnership. Luego, en el ejemplo, se usan estas vistas para crear lo siguiente en un gráfico:
Crea la tabla de nodos
Customercon la vistaAsiaCustomer.Crea la tabla de nodos
Accountcon la vistaAsiaBankAccount.Crea la tabla perimetral
Ownscon la vistaAsiaAccountsOwnership. Este borde conecta los nodosCustomercon los nodosAccount.
Paso 1: Crea las tablas
Primero, crea las tablas de datos. Con el siguiente código, se crean las tablas Customer y
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);
Paso 2: Crea las vistas
Luego, crea vistas para transformar o filtrar datos de las tablas. Estas vistas
filtran las tablas para incluir solo clientes y cuentas de Asia. A menos que
validate_element_key_uniqueness se establezca en false, las vistas que se usan para crear elementos
del grafo deben
seguir patrones admitidos para garantizar que las filas de la vista sean únicas.
-- 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";
Paso 3: Crea el grafo de propiedades
Ahora, crea el AsiaFinGraph con las vistas que creaste. La
sentencia CREATE PROPERTY GRAPH incluye la cláusula KEY para cada definición de elemento
del grafo para especificar las columnas que identifican de forma inequívoca los elementos del grafo.
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)
);
Ejemplos de casos de uso
Las vistas de SQL ofrecen beneficios en comparación con el uso de tablas para los elementos de grafos de propiedades. En los siguientes ejemplos, se muestran algunos casos de uso para definir elementos de grafos con vistas en lugar de tablas.
Ejemplo: Aplica un control de acceso detallado a los datos de grafos
Para aplicar la seguridad a nivel de fila en tus datos de grafo, define tus tablas de nodos o bordes con las vistas de derechos del definidor. La vista expone un subconjunto permitido de los datos subyacentes al gráfico.
Por ejemplo, para restringir el acceso al grafo solo a los empleados de un centro de costos de ingeniería, puedes crear una vista EngineerEmployeeView y otorgar permisos SELECT
en la vista a un rol engineering_data_reader con la cláusula
GRANT.
Cuando defines una tabla de nodos de grafo con esta vista, los usuarios que ejecutan consultas de grafo
con el rol engineering_data_reader solo pueden ver las filas filtradas por la
vista, que incluyen a los empleados de ingeniería.
-- 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)
);
Ejemplo: Elementos del grafo derivados del modelo
Puedes usar vistas para definir elementos de gráficos que requieran transformaciones de datos. Un beneficio clave es que la vista define la transformación, por lo que no necesitas mantener una tabla independiente para los datos derivados.
Anula el anidamiento de arrays para modelar aristas
Por ejemplo, puedes usar UNNEST en los datos de una columna ARRAY (o un campo de array
dentro de una columna JSON) para modelar varias relaciones de borde desde una sola fila.
En el siguiente ejemplo de esquema de cadena de suministro, una tabla Parts almacena una lista de
subcomponentes en un array dependent_parts. Una vista puede usar el operador UNNEST
para transformar cada elemento de ese array en filas distintas. Esta vista
puede servir como una tabla de aristas, lo que te permite modelar una arista PartDependsOnPart para
representar las relaciones de dependencia entre las partes.
-- 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)
);
Calcula propiedades con funciones remotas
También puedes usar una función remota en
una vista para calcular las propiedades derivadas de los elementos del grafo estableciendo
allow_view_with_volatile_column = true en la cláusula OPTIONS de la sentencia CREATE
PROPERTY GRAPH. Para obtener más información, consulta
Habilita columnas volátiles cuando las vistas usen funciones remotas.
-- 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);
Ejemplo: Transición de datos sin esquema
La administración de datos sin esquema te permite crear una definición de grafo flexible sin tipos de nodos y bordes predefinidos. Si bien la administración de datos sin esquema proporciona flexibilidad, es posible que debas realizar la transición a una estructura más formal a medida que tus datos se definan mejor. Una estructura más formal expone las relaciones de nodos y aristas, las etiquetas y las propiedades del grafo en el esquema, lo que reduce la necesidad de explorar los datos de forma manual para comprender el esquema del grafo.
Puedes usar vistas para formalizar los tipos de nodos y aristas sin migrar tus
datos subyacentes. Por ejemplo, puedes realizar la transición de un modelo típico sin esquema
que use tablas canónicas GraphNode y GraphEdge. Para ello, crea
vistas que extraigan los datos de tus tablas sin esquema:
Define una vista para cada tipo de nodo y de borde que quieras formalizar (por ejemplo,
PersonoWorksFor). En la vista, filtra los datos por su etiqueta (por ejemplo,WHERE n_label = "person") y convierte las propiedades de la columna JSON en tipos de datos específicos (por ejemplo,STRING(prop.name) AS name).Define un nuevo gráfico de propiedades en el que
NODE TABLESyEDGE TABLEShagan referencia a las vistas con tipo que acabas de crear.
Un grafo sin esquema proporciona un mejor rendimiento que un grafo formalizado para algunas consultas (por ejemplo, un patrón de ruta cuantificado con varios tipos de bordes). Si los metadatos formalizados son importantes para tu caso de uso, puedes usar vistas para pasar de un grafo sin esquema a un esquema con tipo. También puedes optar por usar un grafo sin esquema para algunos casos de uso y un grafo de esquema con tipo para otros casos de uso. Para obtener más información, consulta Elige un diseño de esquema basado en consultas de grafos.
En el siguiente ejemplo, se muestra el flujo de trabajo para realizar la transición de un grafo sin esquema a uno formalizado en cuatro pasos:
Define las tablas canónicas
GraphNodeyGraphEdgepara el modelo sin esquema.Crear un grafo inicial y flexible en esas tablas sin esquema
Define vistas con tipo (
Person,Company,WorksFor) que extraigan y formalicen los datos de las tablas sin esquema.Crea el grafo final con tipado estático que use estas vistas como sus tablas de nodos y aristas.
-- 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)
);
¿Qué sigue?
Obtén más información sobre los requisitos de unicidad de las claves de elementos.
Obtén información sobre el esquema de Spanner Graph.
Obtén información sobre las prácticas recomendadas para diseñar un esquema de Spanner Graph.