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õesUSE SCHEMA
eCREATE 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égiosUSE SCHEMA
eCREATE 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 comoUSE CATALOG
no catálogo eUSE 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 eUSE 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 deUSE CATALOG
em seus catálogos pai eUSE 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()
: retornaTRUE
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()
: retornaTRUE
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;