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

Consulta cómo 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 aristas. Consulta ejemplos con código de muestra que muestran casos prácticos para crear gráficos con vistas. Para obtener más información sobre cómo usar las vistas para crear un grafo de propiedades, incluidas las ventajas y las consideraciones, consulta el resumen de los grafos creados a partir de vistas de SQL.

Antes de empezar

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

  1. Asegúrate de que tu entorno de Spanner Graph esté configurado.

  2. Familiarízate con cómo funcionan los esquemas de Spanner Graph.

Crear un gráfico con vistas

Para crear un gráfico con vistas, sigue estos pasos:

  1. Define las vistas del gráfico. Asegúrate de que tus vistas sigan uno de los patrones de vista obligatorios. Para obtener más información, consulta el artículo Crear una vista.

  2. Usa tus vistas en las cláusulas NODE TABLES y EDGE TABLES de la instrucción CREATE PROPERTY GRAPH 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.

Ejemplo: Crear un gráfico con vistas

En este ejemplo se crean las siguientes vistas de las tablas Customer y Account: AsiaCustomer, AsiaBankAccount y AsiaAccountsOwnership. A continuación, en el ejemplo se usan 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 aristas Owns con la vista AsiaAccountsOwnership. Esta arista 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

A continuación, cree vistas para transformar o filtrar datos de las tablas. Estas vistas filtran las tablas para incluir solo los clientes y las cuentas de Asia. Las vistas que se usan para crear elementos de gráficos deben asegurarse de 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 has creado. La instrucción CREATE PROPERTY GRAPH incluye la cláusula KEY para cada definición de elemento de gráfico con el fin de especificar las 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 prácticos

Las vistas SQL ofrecen ventajas con respecto al uso de tablas para los elementos de gráficos de propiedades. En los siguientes ejemplos se muestran algunos casos prácticos para definir elementos de gráficos con vistas en lugar de tablas.

Ejemplo: Aplicar un control de acceso pormenorizado a los datos de gráficos

Para aplicar la seguridad a nivel de fila en los datos de tu gráfico, define tus tablas de nodos o aristas mediante vistas de derechos del definidor. La vista muestra un subconjunto permitido de los datos subyacentes del gráfico.

Por ejemplo, para restringir el acceso al gráfico solo a los empleados de un centro de costes de ingeniería, puede crear una vista EngineerEmployeeView y conceder permisos SELECT en la vista a un rol engineering_data_reader mediante la cláusula GRANT.

Cuando defines una tabla de nodos de gráfico con esta vista, los usuarios que ejecuten consultas de gráfico con el rol engineering_data_reader solo podrán 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 de gráfico derivados de un modelo

Puedes usar vistas para definir elementos de gráficos que requieran transformaciones de datos. Una de las principales ventajas es que la vista define la transformación, por lo que no es necesario mantener una tabla independiente para los datos derivados.

Por ejemplo, puedes UNNEST datos de una columna ARRAY (o de un campo de matriz de una columna JSON) para modelar varias relaciones de arista a partir de 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 esa matriz en filas distintas. Esta vista se puede usar como 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)
  );

Ejemplo: transición de datos sin esquema

La gestión de datos sin esquemas te permite crear una definición de gráfico flexible sin tipos de nodos ni de aristas predefinidos. Aunque la gestión de datos sin esquema ofrece flexibilidad, es posible que tengas que pasar a una estructura más formal a medida que tus datos se definan mejor. Una estructura más formal expone las relaciones, las etiquetas y las propiedades de los nodos y los bordes del grafo en el esquema, lo que reduce la necesidad de explorar los datos manualmente para entender el esquema del grafo.

Puedes usar vistas para formalizar los tipos de nodos y aristas sin migrar los datos subyacentes. Por ejemplo, puedes pasar 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:

  1. Define una vista para cada tipo de nodo y arista que quieras 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 donde NODE TABLES y EDGE TABLES hagan referencia a las vistas tipadas que acabas de crear.

Un gráfico sin esquema ofrece un mejor rendimiento que un gráfico formalizado para algunas consultas (por ejemplo, un patrón de ruta cuantificado con varios tipos de aristas). Si los metadatos formalizados son importantes para tu caso práctico, puedes usar vistas para pasar de un gráfico sin esquema a un esquema con tipos. También puedes usar un gráfico sin esquema para algunos casos prácticos y un gráfico de esquema con tipos para otros. Para obtener más información, consulta Elegir un diseño de esquema en función de las consultas de gráficos.

En el siguiente ejemplo se muestra el flujo de trabajo para pasar de un gráfico sin esquema a un gráfico formalizado en cuatro pasos:

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

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

  3. Define vistas tipadas (Person, Company y WorksFor) que extraen y formalizan los datos de las tablas sin esquema.

  4. Crea el gráfico final con tipos definidos que use estas vistas como 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)
  );

Siguientes pasos