Descripción general de los gráficos creados a partir de vistas de SQL

Usa este documento para obtener información sobre los beneficios de usar vistas de SQL para crear un grafo. En este documento, se incluyen los beneficios de crear grafos con vistas, los requisitos y las consideraciones para ayudarte a decidir si debes usar tablas o vistas para crear un grafo.

Para obtener detalles sobre cómo crear un grafo a partir de vistas, consulta Crea un grafo de propiedades a partir de vistas de SQL.

Beneficios de crear grafos con vistas en lugar de tablas

Una vista de SQL es una tabla virtual definida por una consulta en SQL. En Spanner, la consulta que define una vista se ejecuta cada vez que se ejecuta una consulta que hace referencia a la vista. Las vistas de Spanner no son vistas materializadas porque no almacenan los resultados de la consulta que define la vista como una tabla real en el almacén de datos. Para obtener más información, consulta Descripción general de las vistas. Puedes crear elementos de grafo a partir de vistas de SQL, pero no puedes crear una vista que consulte un grafo.

Las vistas proporcionan varias ventajas como una capa de abstracción entre las tablas y un esquema de grafo que no están disponibles cuando usas tablas para crear un grafo.

Requisitos para usar vistas para crear gráficos

Debes cumplir con estos requisitos cuando uses vistas para crear elementos de gráfico:

Usa la cláusula KEY cuando especifiques un elemento de grafo

Debes definir de forma explícita las columnas que identifican de manera única el elemento del grafo cuando usas vistas para crear un nodo o un elemento de borde. Para ello, usa la cláusula KEY en la definición del elemento de nodo o borde. Para aprender a usar la cláusula KEY cuando creas un elemento de grafo, consulta los ejemplos de código de este documento y en Crea un Spanner Graph a partir de una vista de SQL.

Garantiza la unicidad de las claves de nodos y bordes

Cada nodo y arista de un grafo de propiedades debe tener una clave única. Cuando defines elementos de grafo con vistas, puedes elegir cómo se verifica la exclusividad de las claves de los elementos:

Validación estricta de claves (predeterminada)

De forma predeterminada, Spanner verifica que las vistas que definen tablas de nodos o bordes sigan uno de los siguientes patrones para garantizar que cada nodo o borde sea único:

  • Patrón 1: La vista usa la clave primaria de una sola tabla.

  • Patrón 2: La vista usa una cláusula GROUP BY o SELECT DISTINCT.

Puedes usar otros operadores de SQL, como WHERE, HAVING, ORDER BY,LIMIT y TABLESAMPLE, en combinación con estos patrones. Estos operadores filtran o ordenan los resultados, pero no cambian la garantía de unicidad subyacente que proporcionan los patrones.

Patrón 1: Usa la clave primaria de una sola tabla

En este patrón, la vista selecciona de una sola tabla, y la cláusula KEY en la definición del grafo coincide con las columnas de clave primaria de la tabla base. Por este motivo, cada fila de nodo o borde que produce la vista es única.

Por ejemplo, en la siguiente consulta, se selecciona un subconjunto de filas de la tabla Account. El gráfico KEY(account_id) coincide con la clave primaria de la tabla Account, lo que garantiza que cada fila que produce la vista sea única.

-- Table has PRIMARY KEY(account_id).
CREATE TABLE Account (
  account_id INT64 NOT NULL,
  customer_id INT64 NOT NULL,
  account_type STRING(MAX),
  balance INT64
) PRIMARY KEY(account_id);

-- Pattern 1: View uses the primary key from a single table.
CREATE VIEW SavingAccount
  SQL SECURITY INVOKER AS
    SELECT accnt.account_id, accnt.customer_id, accnt.balance
    FROM Account accnt
    WHERE accnt.account_type = 'saving';

CREATE PROPERTY GRAPH SavingAccountGraph
  NODE TABLES (
    -- The element KEY(account_id) matches the table's primary key.
    SavingAccount KEY(account_id)
  );

Patrón 2: Usa la cláusula GROUP BY o SELECT DISTINCT

En este patrón, la consulta de la vista usa una cláusula GROUP BY o SELECT DISTINCT. Las columnas de la cláusula KEY deben coincidir con las columnas que usan estas cláusulas para definir la unicidad:

  • Para GROUP BY: Las columnas de la cláusula KEY deben coincidir con todas las columnas de la cláusula GROUP BY.

  • Para SELECT DISTINCT: Las columnas de la cláusula KEY deben coincidir con las columnas de la lista SELECT DISTINCT.

Ejemplo con GROUP BY:

CREATE TABLE Customer (
  customer_id INT64,
  name STRING(MAX)
) PRIMARY KEY (customer_id);

CREATE TABLE SaleOrder (
  order_id INT64,
  customer_id INT64,
  amount INT64
) PRIMARY KEY (order_id);

CREATE VIEW CustomerOrder
  SQL SECURITY INVOKER AS
    SELECT
      s.order_id,
      ANY_VALUE(c.customer_id) AS customer_id,
      ANY_VALUE(c.name) AS customer_name
    FROM Customer c JOIN SaleOrder s ON c.customer_id = s.customer_id
    GROUP BY s.order_id;

CREATE PROPERTY GRAPH OrderGraph
  NODE TABLES (
    -- The KEY(order_id) matches the GROUP BY column in view definition.
    CustomerOrder KEY(order_id)
  );

Ejemplo con SELECT DISTINCT:

CREATE TABLE SaleOrder (
  order_id INT64,
  customer_id INT64,
  amount INT64
) PRIMARY KEY (order_id);

CREATE VIEW KeyCustomer SQL SECURITY INVOKER AS
  SELECT DISTINCT s.customer_id, s.amount
  FROM SaleOrder s
  WHERE s.amount > 1000;

CREATE PROPERTY GRAPH KeyCustomersGraph
  NODE TABLES (
    -- The KEY(customer_id, amount) matches the DISTINCT columns.
    KeyCustomer KEY(customer_id, amount)
  );

Se inhabilitó la validación de claves (cualquier consulta en SQL)

Si tu vista usa una consulta que no sigue el patrón 1 ni el patrón 2, como una consulta que une tablas sin una cláusula GROUP BY o SELECT DISTINCT, puedes inhabilitar la validación de claves de elementos configurando la opción de grafo validate_element_key_uniqueness = false.

El valor predeterminado de validate_element_key_uniqueness es true. Cuando se establece en false, Spanner no valida la definición de la consulta de la vista en el momento de la creación del esquema. Puedes usar cualquier consulta en SQL en la vista, pero debes asegurarte de que las columnas especificadas en la cláusula KEY contengan valores únicos para cada fila de nodo o borde.

En el siguiente ejemplo, se define una vista llamada CustomerOrderTrusted que une las tablas Customer y SaleOrder sin una cláusula GROUP BY. Como cada pedido de venta es único, unir SaleOrder con Customer conserva la unicidad de order_id en los resultados de la vista. Sin embargo, debido a que la consulta usa un JOIN y no sigue el patrón 1 ni el patrón 2, Spanner no puede verificar la unicidad de forma sintáctica.

Si especificas KEY(order_id) y configuras validate_element_key_uniqueness = false en la cláusula OPTIONS, puedes definir el grafo de propiedades sin modificar la consulta de la vista:

-- View uses a JOIN without GROUP BY or DISTINCT.
CREATE VIEW CustomerOrderTrusted
  SQL SECURITY INVOKER AS
    SELECT
      s.order_id,
      c.customer_id,
      c.name AS customer_name
    FROM Customer c JOIN SaleOrder s ON c.customer_id = s.customer_id;

-- Property graph disables element key uniqueness validation.
CREATE PROPERTY GRAPH OrderGraphTrusted
  NODE TABLES (
    CustomerOrderTrusted
      KEY(order_id)
      LABEL CustomerOrder PROPERTIES(
        order_id,
        customer_id,
        customer_name)
  ) OPTIONS (validate_element_key_uniqueness = false);

Habilita las columnas volátiles cuando las vistas usen funciones remotas

Puedes definir un grafo de propiedades en una vista que llame a una función remota (LANGUAGE REMOTE) estableciendo allow_view_with_volatile_column = true en la cláusula OPTIONS de la sentencia CREATE PROPERTY GRAPH.

De forma predeterminada, Spanner no te permite definir un grafo de propiedades en vistas con columnas volátiles (allow_view_with_volatile_column = false). Una columna de vista es volátil si su expresión llama a una función volátil. Una función es volátil si su valor de retorno puede cambiar incluso dentro de una sola ejecución de sentencia con los mismos argumentos, como una función remota (NOT DETERMINISTIC). Cualquier volatilidad en el cuerpo de definición de una vista, como en una condición JOIN o una cláusula WHERE, también hace que todas las columnas proyectadas en la vista sean volátiles. Para ver un ejemplo de código, consulta Calcula propiedades con funciones remotas.

Consideraciones para usar vistas

Cuando usas vistas para definir elementos de gráficos, lo siguiente puede ayudarte a diseñar y, también, implementar un gráfico eficaz:

Rendimiento de las consultas de grafos de propiedades

Cuando definas elementos de grafo en vistas que realicen transformaciones de datos (por ejemplo, operaciones GROUP BY, UNNEST o JOIN), evalúa con cuidado el rendimiento de las consultas para tu caso de uso. Recuerda que Spanner ejecuta la definición de la consulta de una vista cada vez que una consulta realiza una coincidencia de patrones de elementos.

Optimización del esquema de grafos

Cuando usas vistas para definir elementos de grafo, algunas optimizaciones del esquema de grafo pueden ser menos eficaces que cuando usas tablas para definir elementos de grafo.

Vistas que proyectan la clave primaria de una sola tabla

Si una vista es una proyección de una sola tabla base, cualquier optimización en esa tabla subyacente sigue siendo efectiva para las consultas de grafos. Por ejemplo, aplicar las siguientes técnicas a las tablas base proporciona beneficios de rendimiento similares para los elementos de grafo definidos en esas vistas:

Vistas definidas con la cláusula GROUP BY o DISTINCT

Las vistas que realizan agregaciones, como GROUP BY, SELECT DISTINCT o cualquier otra transformación compleja, pierden la relación directa con la estructura de la tabla subyacente. Por este motivo, es posible que las optimizaciones de esquemas en las tablas base no proporcionen los mismos beneficios de rendimiento para las consultas de grafos que operan en las vistas. Evalúa con cuidado el rendimiento de las consultas para tu caso de uso cuando tus vistas realicen agregaciones complejas.

Modificación de datos con gráficos basados en vistas

Las vistas no se materializan, lo que significa que no almacenan los resultados de la consulta que define la vista como una tabla en el almacén de datos y son de solo lectura. Por este motivo, para insertar, actualizar o descartar nodos o bordes en un grafo creado a partir de vistas, debes modificar los datos de las tablas que se usan para crear las vistas.

Manejo de errores de Graph para aplicar la integridad de los datos

Cuando uses vistas para definir elementos de grafo, aplica la integridad de los datos (por ejemplo, aplica tipos de datos) en las tablas base subyacentes. De lo contrario, los datos de las tablas base podrían no ser válidos y provocar que las consultas en tu grafo basado en vistas fallen en el entorno de ejecución.

Por ejemplo, cuando realizas la transición de un grafo sin esquema a uno formalizado, usa restricciones CHECK para validar los datos en tus tablas base (GraphNode y GraphEdge). El siguiente código aplica estas restricciones dentro de las propiedades JSON para garantizar la integridad de los datos en la fuente y evitar errores de consulta en el entorno de ejecución.

-- Enforce that the 'name' property exists for nodes with the 'person' label.
ALTER TABLE GraphNode
ADD CONSTRAINT NameMustExistForPersonConstraint
CHECK (IF(label = 'person', properties.name IS NOT NULL, TRUE));

-- Enforce that the 'name' property is a string for nodes with the 'person' label.
ALTER TABLE GraphNode
ADD CONSTRAINT PersonNameMustBeStringTypeConstraint
CHECK (IF(label = 'person', JSON_TYPE(properties.name) = 'string', TRUE));

¿Qué sigue?