Criar exibições

Este artigo mostra como criar exibições no Catálogo do Unity.

Uma exibição é um objeto somente leitura composto por uma ou mais tabelas e exibições em um metastore. Uma tabela reside na terceira camada do namespace de três níveis do Catálogo do Unity. Uma exibição pode ser composta por tabelas e exibições em vários esquemas ou catálogos.

Exibições dinâmicas podem ser usadas para fornecer controle de acesso em nível de linha e coluna, além de mascaramento de dados.

Sintaxe de exemplo para criar um modo de exibição:

CREATE VIEW main.default.experienced_employee
  (id COMMENT 'Unique identification number', Name)
  COMMENT 'View for experienced employees'
AS SELECT id, name
   FROM all_employee
   WHERE working_years > 5;

Observação

As exibições poderão ter uma semântica de execução diferente se tiverem suporte de fontes de dados diferentes de tabelas Delta. O Databricks recomenda que você sempre defina as exibições referenciando as fontes de dados usando um nome de exibição ou de tabela. A definição de exibições em conjuntos de dados pela especificação de um caminho ou de um URI pode resultar em requisitos confusos de governança de dados.

Requisitos

Para criar uma exibição:

  • Você deve ter a permissão USE CATALOG no catálogo pai e as permissões USE SCHEMA e CREATE TABLE no esquema pai. Um administrador metastore ou o proprietário do catálogo podem conceder todos esses privilégios. Um proprietário de esquema pode conceder a você os privilégios USE SCHEMA e CREATE TABLE no esquema.
  • Você deve ter a capacidade de ler as tabelas e exibições referenciadas na exibição (SELECT na tabela ou exibição, bem como USE CATALOG no catálogo e USE SCHEMA no esquema).
  • Se uma exibição referenciar tabelas no metastore do Hive local do workspace, o modo de exibição poderá ser acessado somente no workspace que contém as tabelas locais do workspace. Por esse motivo, o Databricks recomenda criar exibições somente de tabelas ou exibições que estejam no metastore do Catálogo do Unity.
  • Você não pode criar uma exibição que referencie a uma exibição que foi compartilhada com você usando o Compartilhamento Delta. Confira Compartilhar dados e ativos de IA com segurança usando o Compartilhamento Delta.

Para ler uma exibição, as permissões necessárias dependem do modo de acesso do cluster:

  • Para clusters compartilhados, você precisa SELECT na própria exibição, USE CATALOG em seu catálogo pai e USE SCHEMA em seu esquema pai.
  • Para clusters de usuário único, você também deve ter SELECT em todas as tabelas e exibições que a exibição referencia, além de USE CATALOG em seus catálogos pai e USE SCHEMA em seus esquemas pai.

Não é possível criar ou ler exibições dinâmicas usando clusters de usuário único.

Criar uma exibição

Para criar uma exibição, execute o comando SQL a seguir. Os itens entre colchetes são opcionais. Substitua os valores de espaço reservado:

  • <catalog-name>: O nome do catálogo.
  • <schema-name>: o nome do esquema.
  • <view-name>: Um nome para a exibição.
  • <query>: A consulta, as colunas, tabelas e exibições usadas para compor a exibição.

SQL

CREATE VIEW <catalog-name>.<schema-name>.<view-name> AS
SELECT <query>;

Python

spark.sql("CREATE VIEW <catalog-name>.<schema-name>.<view-name> AS "
  "SELECT <query>")

R

library(SparkR)

sql(paste("CREATE VIEW <catalog-name>.<schema-name>.<view-name> AS ",
  "SELECT <query>",
  sep = ""))

Scala

spark.sql("CREATE VIEW <catalog-name>.<schema-name>.<view-name> AS " +
  "SELECT <query>")

Por exemplo, para criar uma exibição chamada sales_redacted com base nas colunas da tabela sales_raw:

SQL

CREATE VIEW sales_metastore.sales.sales_redacted AS
SELECT
  user_id,
  email,
  country,
  product,
  total
FROM sales_metastore.sales.sales_raw;

Python

spark.sql("CREATE VIEW sales_metastore.sales.sales_redacted AS "
  "SELECT "
  "  user_id, "
  "  email, "
  "  country, "
  "  product, "
  "  total "
  "FROM sales_metastore.sales.sales_raw")

R

library(SparkR)

sql(paste("CREATE VIEW sales_metastore.sales.sales_redacted AS ",
  "SELECT ",
  "  user_id, ",
  "  email, ",
  "  country, ",
  "  product, ",
  "  total ",
  "FROM sales_metastore.sales.sales_raw",
  sep = ""))

Scala

spark.sql("CREATE VIEW sales_metastore.sales.sales_redacted AS " +
  "SELECT " +
  "  user_id, " +
  "  email, " +
  "  country, " +
  "  product, " +
  "  total " +
  "FROM sales_metastore.sales.sales_raw")

Você também pode criar uma exibição usando o provedor e o databricks_table do Terraform do Databricks. Recupere uma lista de nomes completos de exibição usando o databricks_views.

Criar uma exibição dinâmica

No Catálogo do Unity, você pode usar exibições dinâmicas para configurar o controle de acesso refinado, incluindo:

  • Segurança de nível de colunas ou linhas.
  • Mascaramento de dados.

Observação

O controle de acesso refinado por meio de exibições dinâmicas não está disponível em clusters com o modo de acesso de usuário único.

O Catálogo do Unity apresenta as seguintes funções, que permitem limitar dinamicamente quais usuários podem acessar uma linha, coluna ou um registro em uma exibição:

  • current_user(): retorna o endereço de email do usuário atual.
  • is_account_group_member(): retorna TRUE se o usuário atual é membro de um grupo específico de nível de conta. Recomendado para uso em exibições dinâmicas nos dados do Catálogo do Unity.
  • is_member(): retorna TRUE se o usuário atual é membro de um grupo específico de nível de workspace. Essa função é fornecida para compatibilidade com o metastore do Hive existente. Evite usá-la com exibições nos dados do Catálogo do Unity, pois ela não avalia a associação ao grupo de nível de conta.

O Azure Databricks recomenda que você não conceda aos usuários a capacidade de ler as tabelas e exibições referenciadas na exibição.

Os exemplos a seguir ilustram como criar exibições dinâmicas no Catálogo do Unity.

Permissões de nível de compartilhamento

Com uma exibição dinâmica, você pode limitar as colunas que um usuário ou um grupo específico pode acessar. No exemplo a seguir, somente os membros do grupo auditors podem acessar os endereços de email da tabela sales_raw. Durante a análise de consulta, o Apache Spark substitui a instrução CASE pela cadeia de caracteres literal REDACTED ou pelo conteúdo real da coluna de endereços de email. Outras colunas são retornadas normalmente. Essa estratégia não tem impacto negativo sobre o desempenho da consulta.

SQL

-- Alias the field 'email' to itself (as 'email') to prevent the
-- permission logic from showing up directly in the column name results.
CREATE VIEW sales_redacted AS
SELECT
  user_id,
  CASE WHEN
    is_account_group_member('auditors') THEN email
    ELSE 'REDACTED'
  END AS email,
  country,
  product,
  total
FROM sales_raw

Python

# Alias the field 'email' to itself (as 'email') to prevent the
# permission logic from showing up directly in the column name results.
spark.sql("CREATE VIEW sales_redacted AS "
  "SELECT "
  "  user_id, "
  "  CASE WHEN "
  "    is_account_group_member('auditors') THEN email "
  "  ELSE 'REDACTED' "
  "  END AS email, "
  "  country, "
  "  product, "
  "  total "
  "FROM sales_raw")

R

library(SparkR)

# Alias the field 'email' to itself (as 'email') to prevent the
# permission logic from showing up directly in the column name results.
sql(paste("CREATE VIEW sales_redacted AS ",
  "SELECT ",
  "  user_id, ",
  "  CASE WHEN ",
  "    is_account_group_member('auditors') THEN email ",
  "  ELSE 'REDACTED' ",
  "  END AS email, ",
  "  country, ",
  "  product, ",
  "  total ",
  "FROM sales_raw",
  sep = ""))

Scala

// Alias the field 'email' to itself (as 'email') to prevent the
// permission logic from showing up directly in the column name results.
spark.sql("CREATE VIEW sales_redacted AS " +
  "SELECT " +
  "  user_id, " +
  "  CASE WHEN " +
  "    is_account_group_member('auditors') THEN email " +
  "  ELSE 'REDACTED' " +
  "  END AS email, " +
  "  country, " +
  "  product, " +
  "  total " +
  "FROM sales_raw")

Permissões de nível de linha

Com uma exibição dinâmica, você pode especificar permissões até o nível de linha ou de campo. No exemplo a seguir, somente os membros do grupo managers podem ver os valores de transações quando excederem US$ 1.000.000. Os resultados correspondentes são excluídos para outros usuários.

SQL

 CREATE VIEW sales_redacted AS
 SELECT
   user_id,
   country,
   product,
   total
 FROM sales_raw
 WHERE
   CASE
     WHEN is_account_group_member('managers') THEN TRUE
     ELSE total <= 1000000
   END;

Python

 spark.sql("CREATE VIEW sales_redacted AS "
   "SELECT "
   "  user_id, "
   "  country, "
   "  product, "
   "  total "
   "FROM sales_raw "
   "WHERE "
   "CASE "
   "  WHEN is_account_group_member('managers') THEN TRUE "
   "  ELSE total <= 1000000 "
   "END")

R

 library(SparkR)

 sql(paste("CREATE VIEW sales_redacted AS ",
   "SELECT ",
   "  user_id, ",
   "  country, ",
   "  product, ",
   "  total ",
   "FROM sales_raw ",
   "WHERE ",
   "CASE ",
   "  WHEN is_account_group_member('managers') THEN TRUE ",
   "  ELSE total <= 1000000 ",
   "END",
   sep = ""))

Scala

 spark.sql("CREATE VIEW sales_redacted AS " +
   "SELECT " +
   "  user_id, " +
   "  country, " +
   "  product, " +
   "  total " +
   "FROM sales_raw " +
   "WHERE " +
   "CASE " +
   "  WHEN is_account_group_member('managers') THEN TRUE " +
   "  ELSE total <= 1000000 " +
   "END")

Mascaramento de dados

Como as exibições no Catálogo do Unity usam o Spark SQL, você pode implementar o mascaramento de dados avançado usando expressões SQL mais complexas e expressões regulares. No exemplo a seguir, todos os usuários podem analisar domínios de email, mas somente os membros do grupo auditors podem ver o endereço de email completo de um usuário.

SQL

-- The regexp_extract function takes an email address such as
-- user.x.lastname@example.com and extracts 'example', allowing
-- analysts to query the domain name.

CREATE VIEW sales_redacted AS
SELECT
  user_id,
  region,
  CASE
    WHEN is_account_group_member('auditors') THEN email
    ELSE regexp_extract(email, '^.*@(.*)$', 1)
  END
  FROM sales_raw

Python

# The regexp_extract function takes an email address such as
# user.x.lastname@example.com and extracts 'example', allowing
# analysts to query the domain name.

spark.sql("CREATE VIEW sales_redacted AS "
  "SELECT "
  "  user_id, "
  "  region, "
  "  CASE "
  "    WHEN is_account_group_member('auditors') THEN email "
  "    ELSE regexp_extract(email, '^.*@(.*)$', 1) "
  "  END "
  "  FROM sales_raw")

R

library(SparkR)

# The regexp_extract function takes an email address such as
# user.x.lastname@example.com and extracts 'example', allowing
# analysts to query the domain name.

sql(paste("CREATE VIEW sales_redacted AS ",
  "SELECT ",
  "  user_id, ",
  "  region, ",
  "  CASE ",
  "    WHEN is_account_group_member('auditors') THEN email ",
  "    ELSE regexp_extract(email, '^.*@(.*)$', 1) ",
  "  END ",
  "  FROM sales_raw",
  sep = ""))

Scala

// The regexp_extract function takes an email address such as
// user.x.lastname@example.com and extracts 'example', allowing
// analysts to query the domain name.

spark.sql("CREATE VIEW sales_redacted AS " +
  "SELECT " +
  "  user_id, " +
  "  region, " +
  "  CASE " +
  "    WHEN is_account_group_member('auditors') THEN email " +
  "    ELSE regexp_extract(email, '^.*@(.*)$', 1) " +
  "  END " +
  "  FROM sales_raw")

Remover uma exibição

Você deve ser o proprietário da exibição para remover uma exibição. Para criar uma exibição, execute o comando SQL a seguir.

DROP VIEW IF EXISTS catalog_name.schema_name.view_name;

Próximas etapas