뷰 만들기
이 문서에서는 Unity 카탈로그에서 뷰를 만드는 방법을 보여 줍니다.
뷰는 메타스토어에 있는 하나 이상의 테이블과 뷰에서 구성된 읽기 전용 개체입니다. Unity 카탈로그 세 수준 네임스페이스의 세 번째 계층에 있습니다. 여러 스키마 및 카탈로그의 테이블 및 기타 뷰에서 뷰를 작성할 수 있습니다.
동적 뷰는 데이터 마스킹 외에도 행 및 열 수준 액세스 제어를 제공하는 데 사용할 수 있습니다.
뷰 만들기 구문의 예:
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;
참고 항목
뷰는 델타 테이블 이외의 데이터 원본에서 지원되는 경우 다른 실행 의미 체계를 가질 수 있습니다. Databricks는 테이블 또는 뷰 이름을 사용하여 데이터 원본을 참조하여 항상 뷰를 정의하는 것이 좋습니다. 경로 또는 URI를 지정하여 데이터 세트에 대한 뷰를 정의하면 데이터 거버넌스 요구 사항이 혼란스러울 수 있습니다.
요구 사항
보기를 만들려면 다음을 수행합니다.
- 부모 카탈로그에 대한
USE CATALOG
권한과 부모 스키마에 대한USE SCHEMA
및CREATE TABLE
권한이 있어야 합니다. 메타스토어 관리자 또는 카탈로그 소유자가 이러한 모든 권한을 사용자에게 부여할 수 있습니다. 스키마 소유자는 스키마에 대해USE SCHEMA
및CREATE TABLE
권한을 사용자에게 부여할 수 있습니다. - 뷰에서 참조되는 테이블과 뷰를 읽을 수 있어야 합니다(
SELECT
테이블 또는 뷰와USE CATALOG
카탈로그 및USE SCHEMA
스키마). - 뷰가 작업 영역 로컬 Hive 메타스토어의 테이블을 참조하는 경우 작업 영역 로컬 테이블이 포함된 작업 영역에서만 뷰에 액세스할 수 있습니다. 이러한 이유로 Databricks는 Unity 카탈로그 메타스토어에 있는 테이블 또는 뷰에서만 뷰를 만들 것을 권장합니다.
- 델타 공유를 사용하여 공유된 뷰를 참조하는 뷰는 만들 수 없습니다. 델타 공유를 사용하여 안전하게 데이터 및 AI 자산 공유를 참조하세요.
보기를 읽으려면 필요한 권한은 컴퓨팅 유형 및 액세스 모드에 따라 달라집니다.
- 공유 클러스터 및 SQL 웨어하우스의 경우 뷰 자체,
USE CATALOG
부모 카탈로그 및USE SCHEMA
부모 스키마에 필요합니다SELECT
. - 단일 사용자 클러스터의 경우 부모 카탈로그 및 부모 스키마 외에도
USE CATALOG
보기에서 참조하는 모든 테이블과USE SCHEMA
뷰에 있어야 합니다SELECT
.
동적 보기를 만들거나 읽으려면 다음을 수행합니다.
- 동적 보기에 대한 요구 사항은 공유 클러스터 또는 SQL 웨어하우스를 사용하여 동적 보기를 만들거나 읽어야 한다는 점을 제외하고 이전 섹션에 나열된 것과 동일합니다. 단일 사용자 클러스터는 사용할 수 없습니다.
보기 만들기
보기를 만들려면 다음 SQL 명령을 실행합니다. 괄호 안의 항목은 선택 사항입니다. 자리 표시자 값을 바꿉니다.
<catalog-name>
: 카탈로그의 이름입니다.<schema-name>
: 스키마의 이름입니다.<view-name>
: 보기의 이름입니다.<query>
: 보기를 구성하는 데 사용되는 쿼리, 열, 테이블 및 보기입니다.
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>")
예를 들어, sales_raw
테이블의 열에서 sales_redacted
이라는 뷰를 만들려면:
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")
Databricks Terraform 공급자 및 databricks_table을 사용하여 보기를 만들 수도 있습니다. databricks_views를 사용하여 보기 전체 이름 목록을 검색할 수 있습니다.
동적 뷰 만들기
Unity 카탈로그에서 동적 뷰를 사용하여 다음을 비롯한 세분화된 액세스 제어를 구성할 수 있습니다.
- 열 또는 행 수준의 보안.
- 데이터 마스킹.
참고 항목
동적 뷰를 사용하는 세분화된 액세스 제어는 단일 사용자액세스 모드의 클러스터에서 사용할 수 없습니다.
Unity 카탈로그에는 뷰에서 행, 열 또는 레코드에 액세스할 수 있는 사용자를 동적으로 제한할 수 있는 다음 함수가 도입되었습니다.
current_user()
: 현재 사용자의 이메일 주소를 반환합니다.is_account_group_member()
: 현재 사용자가 특정 계정 수준 그룹의 멤버면TRUE
를 반환합니다. Unity 카탈로그 데이터는 동적 뷰에서 사용하는 것을 권장합니다.is_member()
: 현재 사용자가 특정 작업 영역 수준 그룹의 멤버면TRUE
를 반환합니다. 이 함수는 기존 Hive 메타스토어와의 호환성을 위해 제공됩니다. 계정 수준의 그룹 멤버 자격을 평가하지 않으므로 Unity 카탈로그 데이터에 대한 뷰와 함께 사용하지 마세요.
Azure Databricks는 사용자에게 보기에서 참조되는 테이블 및 뷰를 읽을 수 있는 기능을 부여하지 않는 것이 좋습니다.
다음 예제에서는 Unity 카탈로그에서 동적 뷰를 만드는 방법을 보여 줍니다.
서버 수준 사용 권한
동적 뷰를 사용하면 특정 사용자 또는 그룹이 액세스할 수 있는 열을 제한할 수 있습니다. 다음 예제에서는 auditors
그룹의 멤버만 sales_raw
테이블의 이메일 주소에 액세스할 수 있습니다. 쿼리 분석 중에 Apache Spark는 CASE
문을 리터럴 문자열 REDACTED
또는 이메일 주소 열의 실제 내용으로 바꿉니다. 다른 열은 정상적으로 반환됩니다. 이 전략은 쿼리 성능에 부정적인 영향을 주지 않습니다.
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")
행 수준 권한
동적 뷰를 사용하면 행 또는 필드 수준까지 권한을 지정할 수 있습니다. 다음 예제에서는 트랜잭션 금액이 $1,000,000를 초과하는 경우 managers
그룹의 멤버만 트랜잭션 금액을 볼 수 있습니다. 일치하는 결과 중 다른 사용자의 결과는 필터링됩니다.
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")
데이터 마스킹
Unity 카탈로그의 뷰는 Spark SQL을 사용하므로 더 복잡한 SQL 식과 정규식을 사용하여 고급 데이터 마스킹을 구현할 수 있습니다. 다음 예에서는 모든 사용자가 이메일 도메인을 분석할 수 있지만 auditors
그룹의 멤버만 사용자의 전체 이메일 주소를 볼 수 있습니다.
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")
뷰 삭제
보기를 삭제하려면 보기의 소유자여야 합니다. 보기를 삭제하려면 다음 SQL 명령을 실행합니다.
DROP VIEW IF EXISTS catalog_name.schema_name.view_name;