Visão geral dos gráficos criados com visualizações SQL

Use este documento para saber mais sobre os benefícios de usar visualizações SQL para criar um gráfico. Este documento inclui benefícios de criar gráficos com visualizações, requisitos e considerações para ajudar você a decidir se deve usar tabelas ou visualizações para criar um gráfico.

Para detalhes sobre como criar um gráfico de visualizações, consulte Criar um gráfico de propriedades de visualizações SQL.

Benefícios de criar gráficos com visualizações em vez de tabelas

Uma visualização SQL é uma tabela virtual definida por uma consulta SQL. No Spanner, a consulta que define uma visualização é executada sempre que uma consulta que se refere a ela é executada. As visualizações do Spanner não são materializadas porque não armazenam os resultados da consulta que define a visualização como uma tabela real no armazenamento de dados. Para mais informações, consulte Visão geral das visualizações. É possível criar elementos de gráfico com base em visualizações SQL, mas não é possível criar uma visualização que consulte um gráfico.

As visualizações oferecem várias vantagens como uma camada de abstração entre tabelas e um esquema de gráfico que não estão disponíveis quando você usa tabelas para criar um gráfico.

Requisitos para usar visualizações e criar gráficos

É necessário seguir estes requisitos ao usar visualizações para criar elementos de gráfico:

Use a cláusula KEY ao especificar um elemento de gráfico.

É preciso definir explicitamente as colunas que identificam de forma exclusiva o elemento do gráfico ao usar visualizações para criar um nó ou uma aresta. Para fazer isso, use a cláusula KEY na definição do elemento de nó ou aresta. Para saber como usar a cláusula KEY ao criar um elemento de gráfico, consulte os exemplos de código neste documento e em Criar um gráfico do Spanner com base em uma visualização SQL.

Usar visualizações que garantam que nós e arestas sejam únicos

As visualizações que definem tabelas de nós ou arestas precisam seguir um dos padrões abaixo para garantir que os nós e as arestas sejam únicos:

  • Padrão 1: a visualização usa a chave primária de uma única tabela.

  • Padrão 2: a visualização usa uma cláusula GROUP BY ou SELECT DISTINCT.

É possível usar outros operadores SQL, como WHERE, HAVING, ORDER BY, LIMIT e TABLESAMPLE, em combinação com esses padrões. Esses operadores filtram ou ordenam os resultados, mas não mudam a garantia de exclusividade que os padrões oferecem.

Padrão 1: usar a chave primária de uma única tabela

Nesse padrão, a visualização seleciona uma única tabela, e a cláusula KEY na definição do gráfico corresponde às colunas de chave primária da tabela base. Por isso, cada nó ou linha de aresta produzido pela visualização é único.

Por exemplo, o comando a seguir seleciona um subconjunto de linhas da tabela Account. O gráfico KEY(account_id) corresponde à chave primária da tabela Account, o que garante que cada linha produzida pela visualização seja ú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)
  );

Padrão 2: usar a cláusula GROUP BY ou SELECT DISTINCT

Nesse padrão, a consulta da visualização usa uma cláusula GROUP BY ou SELECT DISTINCT. As colunas na cláusula KEY precisam corresponder às colunas que essas cláusulas usam para definir a exclusividade:

  • Para GROUP BY: as colunas da cláusula KEY precisam corresponder a todas as colunas na cláusula GROUP BY.

  • Para SELECT DISTINCT: as colunas da cláusula KEY precisam corresponder às colunas na lista SELECT DISTINCT.

Exemplo com 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)
  );

Exemplo com 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)
  );

Considerações ao usar visualizações

Ao usar visualizações para definir elementos do gráfico, o seguinte pode ajudar você a projetar e implementar um gráfico eficaz:

Performance de consultas de gráficos de propriedades

Ao definir elementos de gráfico em visualizações que realizam transformações de dados (por exemplo, operações GROUP BY, UNNEST ou JOIN), avalie com cuidado a performance da consulta para seu caso de uso. O Spanner executa a definição de consulta de uma visualização sempre que uma consulta realiza uma correspondência de padrões de elementos.

Otimização do esquema de gráfico

Ao usar visualizações para definir elementos de gráfico, algumas otimizações de esquema de gráfico podem ser menos eficazes do que quando você usa tabelas para definir elementos de gráfico.

Visualizações que projetam a chave primária de uma única tabela

Se uma visualização for uma projeção de uma única tabela de base, todas as otimizações nessa tabela subjacente vão continuar sendo eficazes para consultas de gráficos. Por exemplo, aplicar as técnicas a seguir às tabelas de base oferece benefícios de desempenho semelhantes para elementos de gráfico definidos nessas visualizações:

Visualizações definidas com a cláusula GROUP BY ou DISTINCT

As visualizações que realizam agregações, como GROUP BY, SELECT DISTINCT ou outras transformações complexas, perdem a relação direta com a estrutura da tabela subjacente. Por isso, as otimizações de esquema nas tabelas de base podem não oferecer os mesmos benefícios de desempenho para consultas de gráficos que operam nas visualizações. Avalie com cuidado a performance da consulta para seu caso de uso quando as visualizações realizarem agregações complexas.

Modificação de dados com gráficos baseados em visualizações

As visualizações não são materializadas, o que significa que elas não armazenam os resultados da consulta que define a visualização como uma tabela no armazenamento de dados, e são somente leitura. Por isso, para inserir, atualizar ou descartar nós ou arestas em um gráfico criado com base em visualizações, modifique os dados nas tabelas usadas para criar as visualizações.

Tratamento de erros de gráficos para garantir a integridade dos dados

Ao usar visualizações para definir elementos de gráfico, aplique a integridade dos dados (por exemplo, tipos de dados) nas tabelas de base subjacentes. Caso contrário, os dados nas tabelas base podem ser inválidos e causar falhas nas consultas no gráfico baseado em visualização durante a execução.

Por exemplo, ao fazer a transição de um gráfico sem esquema para um formalizado, use restrições CHECK para validar os dados nas tabelas de base (GraphNode e GraphEdge). O código a seguir aplica essas restrições nas propriedades JSON para garantir a integridade dos dados na origem e evitar erros de consulta em tempo de execução.

-- 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));

A seguir