Crea un gráfico a partir de una vista de SQL

Aprende a crear un gráfico 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 demuestran casos de uso para crear gráficos con vistas. Para obtener más información sobre el uso de vistas para crear un gráfico de propiedades, incluidos los beneficios y las consideraciones, consulta Descripción general de los gráficos creados a partir de vistas de SQL.

Antes de comenzar

Para crear un gráfico, debes hacer lo siguiente:

  1. Asegurarte de que tu entorno de Spanner Graph esté configurado.

  2. Familiarizarte con el funcionamiento de los esquemas de Spanner Graph.

Crea un gráfico con vistas

Para crear un gráfico con vistas, haz lo siguiente:

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

  2. Usa tus vistas en las cláusulas NODE TABLES y EDGE TABLES de la CREATE PROPERTY GRAPH instrucción para crear un gráfico.

  3. Incluye la cláusula KEY en la instrucción CREATE PROPERTY GRAPH. La cláusula KEY especifica las columnas de la vista de origen que identifican de forma única cada elemento del gráfico.

  4. Opcional: Si tus vistas usan consultas de SQL arbitrarias que no siguen los patrones de unicidad admitidos, agrega la cláusula OPTIONS (validate_element_key_uniqueness = false) a la instrucción CREATE PROPERTY GRAPH. Asegúrate de que las columnas de la cláusula KEY produzcan valores únicos para cada fila de nodo o 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 inhabilitada (cualquier consulta en SQL).

Ejemplo: Crea un gráfico con vistas

En este ejemplo, se crean las siguientes vistas sobre las tablas Customer y Account: AsiaCustomer, AsiaBankAccount y AsiaAccountsOwnership. Luego, el ejemplo usa estas vistas para crear lo siguiente en un gráfico:

  • Crea la tabla de nodos Customer con la vista AsiaCustomer.

  • Crea la tabla de nodos Account con la vista AsiaBankAccount.

  • Crea la tabla de bordes Owns con la vista AsiaAccountsOwnership. Este borde conecta nodos Customer con nodos Account.

Paso 1: Crea las tablas

Primero, crea las tablas de datos. El siguiente código crea 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 en Asia. A menos que validate_element_key_uniqueness se establezca en false, las vistas que se usan para crear elementos de gráfico 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 gráfico de propiedades

Ahora, crea el AsiaFinGraph con las vistas que creaste. La instrucción CREATE PROPERTY GRAPH incluye la cláusula KEY para cada definición de elemento de gráfico para especificar columnas que identifican de forma única los elementos del gráfico.

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 elementos de gráficos de propiedades. En los siguientes ejemplos, se muestran algunos casos de uso para definir elementos de gráficos con vistas en lugar de tablas.

Ejemplo: Aplica el control de acceso detallado a los datos del gráfico

Para aplicar la seguridad a nivel de fila en los datos del gráfico, define las tablas de nodos o bordes con 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 gráfico 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 gráfico con esta vista, los usuarios que ejecutan consultas de gráficos con el rol engineering_data_reader solo pueden ver las filas filtradas por la vista, que incluyen 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: Modela elementos de gráficos derivados

Puedes usar vistas para definir elementos de gráficos que requieren transformaciones de datos. Un beneficio clave es que la vista define la transformación, por lo que no necesitas mantener una tabla separada para los datos derivados.

Por ejemplo, puedes UNNEST 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. Luego, esta vista puede servir como una tabla de bordes, lo que te permite modelar un borde 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)
  );

Ejemplo: Transición de datos sin esquema

La administración de datos sin esquema te permite crear una definición de gráfico 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 se definan mejor tus datos. Una estructura más formal expone las relaciones, las etiquetas y las propiedades de los nodos y bordes del gráfico en el esquema, lo que reduce la necesidad de exploración manual de datos para comprender el esquema del gráfico.

Puedes usar vistas para formalizar los tipos de nodos y bordes sin migrar los datos subyacentes. Por ejemplo, puedes realizar la transición de un modelo típico sin esquema que usa tablas canónicas GraphNode y GraphEdge. Para ello, crea vistas que extraigan los datos de tus tablas sin esquema:

  1. Define una vista para cada tipo de nodo y borde que deseas formalizar (por ejemplo, Person o WorksFor). 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).

  2. Define un nuevo gráfico de propiedades en el que NODE TABLES y EDGE TABLES hagan referencia a las vistas con tipo que acabas de crear.

Un gráfico sin esquema proporciona un mejor rendimiento que un gráfico 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 realizar la transición de un gráfico sin esquema a un esquema con tipo. También puedes elegir usar un gráfico sin esquema para algunos casos de uso y un gráfico de esquema con tipo para otros. Para obtener más información, consulta Elige un diseño de esquema basado en consultas de gráficos.

En el siguiente ejemplo, se muestra el flujo de trabajo para realizar la transición de un gráfico sin esquema a uno formalizado en cuatro pasos:

  1. Define las tablas canónicas GraphNode y GraphEdge para el modelo sin esquema.

  2. Crea un gráfico inicial y flexible en esas tablas sin esquema.

  3. Define vistas con tipo (Person, Company, WorksFor) que extraigan y formalicen los datos de las tablas sin esquema.

  4. Crea el gráfico final con tipo seguro que usa estas vistas como sus tablas de nodos y bordes.

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