As restrições de chave primária e chave estrangeira são GA e agora permitem consultas mais rápidas


A Dataricks tem o prazer de anunciar as restrições de Disponibilidade Geral (GA) de Chave Primária (PK) e Chave Estrangeira (FK), começando no Databricks Runtime 15.2 e no Databricks SQL 2024.30. Este lançamento segue uma prévia pública de grande sucesso, adotada por centenas de clientes ativos semanais, e representa ainda mais um marco significativo no aprimoramento da integridade dos dados e do gerenciamento de dados relacionais dentro do Lakehouse.

Além disso, o Databricks agora pode usar essas restrições para otimizar consultas e eliminar operações desnecessárias do plano de consulta, proporcionando um desempenho muito mais rápido.

Restrições de chave primária e chave estrangeira

Chaves Primárias (PKs) e Chaves Estrangeiras (FKs) são elementos essenciais em bancos de dados relacionais, atuando como blocos de construção fundamentais para modelagem de dados. Elas fornecem informações sobre os relacionamentos de dados no esquema para usuários, ferramentas e aplicativos; e permitem otimizações que alavancam restrições para acelerar consultas. Chaves primárias e estrangeiras agora estão geralmente disponíveis para suas tabelas Delta Lake hospedadas no Unity Catalog.

Linguagem SQL

Você pode definir restrições ao criar uma tabela:

CREATE TABLE Customers (
    UserID INT NOT NULL PRIMARY KEY,
    UserName STRING,
    E mail STRING,
    SignUpDate DATE
);

No exemplo acima, definimos uma restrição de chave primária na coluna UserID. O Databricks também suporta restrições em grupos de colunas.

Você também pode modificar tabelas Delta existentes para adicionar ou remover restrições:

CREATE TABLE Merchandise (
    ProductID INT NOT NULL,
    ProductName STRING,
    Value DECIMAL(10,2),
    CategoryID INT
);
ALTER TABLE Merchandise ADD CONSTRAINT products_pk PRIMARY KEY (ProductID);
ALTER TABLE Merchandise DROP CONSTRAINT products_pk;

Aqui criamos a chave primária chamada products_pk na coluna não anulável ProductID em uma tabela existente. Para executar esta operação com sucesso, você deve ser o proprietário da tabela. Observe que os nomes de restrição devem ser exclusivos dentro do esquema.
O comando subsequente take away a chave primária especificando o nome.

O mesmo processo se aplica para chaves estrangeiras. A tabela a seguir outline duas chaves estrangeiras no momento da criação da tabela:

CREATE TABLE Purchases (
    PurchaseID INT PRIMARY KEY,
    UserID INT,
    ProductID INT,
    PurchaseDate DATE,
    Amount INT,
    FOREIGN KEY (UserID) REFERENCES Customers(UserID),
    FOREIGN KEY (ProductID) REFERENCES Merchandise(ProductID)
);

Consulte a documentação em CRIAR A TABELA e ALTERAR A TABELA instruções para mais detalhes sobre a sintaxe e as operações relacionadas às restrições.

Restrições de chave primária e chave estrangeira não são impostas no mecanismo do Databricks, mas podem ser úteis para indicar um relacionamento de integridade de dados que deve ser verdadeiro. O Databricks pode, em vez disso, impor restrições de chave primária upstream como parte do pipeline de ingestão. Veja Qualidade de dados gerenciada com Delta Stay Tables para mais informações sobre restrições impostas. O Databricks também oferece suporte a restrições impostas NOT NULL e CHECK restrições (veja o Documentação de restrições Para maiores informações).

Ecossistema de parceiros

Ferramentas e aplicativos como a versão mais recente do Tableau e do PowerBI podem importar e utilizar automaticamente seus relacionamentos de chave primária e chave estrangeira do Databricks por meio de conectores JDBC e ODBC.

Ver as restrições

Existem várias maneiras de visualizar as restrições de chave primária e de chave estrangeira definidas na tabela. Você também pode simplesmente usar comandos SQL para visualizar informações de restrição com o DESCRIBE TABLE EXTENDED comando:

> DESCRIBE TABLE EXTENDED Purchases

... (omitting different outputs)
# Constraints	
purchases_pk             PRIMARY KEY (`PurchaseID`)
purchases_products_fk    FOREIGN KEY (`ProductID`) REFERENCES `foremost`
                         .`instance`.`merchandise` (`ProductID`)
purchases_users_fk       FOREIGN KEY (`UserID`) REFERENCES `foremost`
                         .`instance`.`customers` (`UserID`)

Diagrama de relacionamento do Catalog Explorer e da entidade

Você também pode visualizar as informações de restrições por meio do Explorador de catálogo:

As restrições de chave primária e chave estrangeira são GA e agora permitem consultas mais rápidas

Cada coluna de chave primária e chave estrangeira tem um pequeno ícone de chave ao lado do seu nome.

E você pode visualizar as informações da chave primária e estrangeira e os relacionamentos entre as tabelas com o Diagrama de relacionamento de entidade no Catalog Explorer. Abaixo está um exemplo de uma tabela purchases referenciando duas tabelas, customers e merchandise:

Diagrama de relacionamento de entidade

ESQUEMA DE INFORMAÇÕES

A seguir ESQUEMA_DE_INFORMAÇÕES as tabelas também fornecem informações sobre restrições:

Use a opção RELY para habilitar otimizações

Se você sabe que a restrição de chave primária é válida (por exemplo, porque seu pipeline de dados ou tarefa ETL a impõe), você pode habilitar otimizações com base na restrição especificando-a com a opção RELY, como:

PRIMARY KEY (c_customer_sk) RELY

Usar a opção RELY permite que o Databricks otimize consultas de maneiras que dependem da validade da restrição, porque você está garantindo que a integridade dos dados seja mantida. Tenha cuidado aqui porque se uma restrição for marcada como RELY, mas os dados violarem a restrição, suas consultas podem retornar resultados incorretos.

Quando você não especifica a opção RELY para uma restrição, o padrão é NORELY, caso em que as restrições ainda podem ser usadas para fins informativos ou estatísticos, mas as consultas não dependerão delas para serem executadas corretamente.

A opção RELY e as otimizações que a utilizam estão atualmente disponíveis para chaves primárias e também estarão disponíveis em breve para chaves estrangeiras.

Você pode modificar a chave primária de uma tabela para alterar se ela é RELY ou NORELY usando ALTER TABLE, por exemplo:

ALTER TABLE buyer DROP PRIMARY KEY;
ALTER TABLE buyer ADD PRIMARY KEY (c_customer_sk) RELY

Acelere suas consultas eliminando agregações desnecessárias

Uma otimização simples que podemos fazer com restrições de chave primária RELY é eliminar agregados desnecessários. Por exemplo, em uma consulta que está aplicando uma operação distinta sobre uma tabela com uma chave primária usando RELY:

SELECT DISTINCT c_customer_sk FROM buyer;

Podemos remover a operação DISTINCT desnecessária:

SELECT c_customer_sk FROM buyer;

Como você pode ver, essa consulta depende da validade da restrição de chave primária RELY – se houver IDs de clientes duplicados na tabela de clientes, a consulta transformada retornará resultados duplicados incorretos. Você é responsável por impor a validade da restrição se definir a opção RELY.

Se a chave primária for NORELY (o padrão), o otimizador não removerá a operação DISTINCT da consulta. Então, ele pode ficar mais lento, mas sempre retorna resultados corretos, mesmo se houver duplicatas. Se a chave primária for RELY, o Databricks pode remover a operação DISTINCT, o que pode acelerar muito a consulta – em cerca de 2x para o exemplo acima.

Acelere suas consultas eliminando junções desnecessárias

Outra otimização muito útil que podemos executar com chaves primárias RELY é eliminar junções desnecessárias. Se uma consulta une uma tabela que não é referenciada em nenhum lugar, exceto na condição de junção, então o otimizador pode determinar que a junção é desnecessária e remover a junção do plano de consulta.

Para dar um exemplo, digamos que temos uma consulta unindo duas tabelas, store_sales e buyerunido na chave primária da tabela do cliente PRIMARY KEY (c_customer_sk) RELY.

SELECT SUM(ss_quantity)
FROM store_sales ss
LEFT JOIN buyer c
ON ss_customer_sk = c_customer_sk;

Se não tivéssemos a chave primária, cada linha de store_sales poderia potencialmente corresponder a várias linhas em buyere precisaríamos executar a junção para calcular o valor SUM correto. Mas como a tabela buyer é unido em sua chave primária, sabemos que a junção produzirá uma linha para cada linha de store_sales.

Então a consulta só precisa da coluna ss_quantity da tabela de fatos store_sales. Portanto, o otimizador de consulta pode eliminar completamente a junção da consulta, transformando-a em:

SELECT SUM(ss_quantity)
FROM store_sales ss

Isso é executado muito mais rápido evitando a junção inteira – neste exemplo, observamos a otimização acelerando a consulta de 1,5 minutos a 6 segundos!. E os benefícios podem ser ainda maiores quando a junção envolve muitas tabelas que podem ser eliminadas!

Diagrama de Eliminação

Você pode perguntar, por que alguém executaria uma consulta como essa? Na verdade, é muito mais comum do que você imagina! Um motivo comum é que os usuários constroem visualizações que unem várias tabelas, como unir muitas tabelas de fatos e dimensões. Eles escrevem consultas sobre essas visualizações que geralmente usam colunas de apenas algumas das tabelas, não de todas – e assim o otimizador pode eliminar as junções nas tabelas que não são necessárias em cada consulta. Esse padrão também é comum em muitas ferramentas de Enterprise Intelligence (BI), que geralmente geram consultas unindo muitas tabelas em um esquema, mesmo quando uma consulta usa apenas colunas de algumas das tabelas.

Conclusão

Desde sua prévia pública, mais de 2600 clientes do Databricks usaram restrições de chave primária e chave estrangeira. Hoje, estamos animados em anunciar a disponibilidade geral desse recurso, marcando uma nova etapa em nosso compromisso de aprimorar o gerenciamento e a integridade de dados no Databricks.

Além disso, o Databricks agora aproveita as principais restrições com a opção RELY para otimizar consultas, como eliminando agregados e junções desnecessários, resultando em um desempenho de consulta muito mais rápido.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *