ビュー の作成
この記事では、 Unity Catalogでビューを作成する方法について説明します。
ビューは、メタストア内の 1 つ以上のテーブルとビューから構成される読み取り専用オブジェクトです。 これは、Unity Catalog の 3 レベルの名前空間の 3 番目のレイヤーに存在します。 ビューは、複数のスキーマおよびカタログ内のテーブルおよびその他のビューから作成できます。
動的ビュー を使用すると、データマスキングに加えて、行レベルおよび列レベルのアクセス制御を提供できます。
ビューを作成するための構文の例:
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;
注
ビューの実行セマンティクスは、Delta テーブル以外のデータソースによってサポートされている場合、異なる可能性があります。 Databricks では、常にテーブル名またはビュー名を使用してデータソースを参照してビューを定義することをお勧めします。 パスまたは URI を指定してデータセットに対するビューを定義すると、データガバナンス要件が混乱する可能性があります。
要件
ビューを作成するには、次のようにします。
親カタログに対する
USE CATALOG
権限と、親スキーマに対するUSE SCHEMA
権限とCREATE TABLE
権限が必要です。 メタストア管理者またはカタログ所有者は、これらすべての権限を付与できます。 スキーマ所有者は、スキーマに対するUSE SCHEMA
およびCREATE TABLE
権限を付与できます。ビューで参照される表とビュー (表またはビューの
SELECT
、カタログのUSE CATALOG
、スキーマのUSE SCHEMA
) を読み取ることができる必要があります。ビューがワークスペースローカル Hive metastore内のテーブルを参照する場合、そのビューにはワークスペースローカルテーブルを含むワークスペースからのみアクセスできます。 このため、Databricks では、 Unity Catalog メタストア内のテーブルまたはビューからのみビューを作成することをお勧めします。
Delta Sharingを使用して共有されているビューを参照するビューを作成することはできません。 Delta Sharing使用してデータと AI アセットを安全に共有するを参照してください。
ビューを読み取るために必要な権限は、コンピュート タイプとアクセス モードによって異なります。
共有 クラスター および SQL ウェアハウスの場合、ビュー自体に
SELECT
、その親カタログにUSE CATALOG
、その親スキーマにUSE SCHEMA
必要です。シングルユーザー クラスターの場合、親カタログの
USE CATALOG
と親スキーマのUSE SCHEMA
に加えて、ビューが参照するすべてのテーブルとビューにSELECT
も必要です。
動的ビューを作成または読み取るには、次のようにします。
動的ビューの要件は、前のセクションで説明したものと同じですが、動的ビューを作成または読み取るには共有クラスターまたは SQL Server を使用する必要があります。 シングルユーザー クラスターは使用できません。
ビュー を作成する
ビューを作成するには、次の SQL コマンドを実行します。 括弧内の項目はオプションです。 プレースホルダー値を置き換えます。
<catalog-name>
:カタログの名前。<schema-name>
:スキーマの名前。<view-name>
: ビューの名前。<query>
: クエリー、列、およびビューを構成するために使用されるテーブルとビュー。
CREATE VIEW <catalog-name>.<schema-name>.<view-name> AS
SELECT <query>;
spark.sql("CREATE VIEW <catalog-name>.<schema-name>.<view-name> AS "
"SELECT <query>")
library(SparkR)
sql(paste("CREATE VIEW <catalog-name>.<schema-name>.<view-name> AS ",
"SELECT <query>",
sep = ""))
spark.sql("CREATE VIEW <catalog-name>.<schema-name>.<view-name> AS " +
"SELECT <query>")
たとえば、 sales_raw
テーブルの列から sales_redacted
という名前のビューを作成するには、次のようにします。
CREATE VIEW sales_metastore.sales.sales_redacted AS
SELECT
user_id,
email,
country,
product,
total
FROM sales_metastore.sales.sales_raw;
spark.sql("CREATE VIEW sales_metastore.sales.sales_redacted AS "
"SELECT "
" user_id, "
" email, "
" country, "
" product, "
" total "
"FROM sales_metastore.sales.sales_raw")
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 = ""))
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 Catalogでは、動的ビューを使用して、次のようなきめ細かなアクセス制御を構成できます。
列または行のレベルのセキュリティ。
データマスキング.
注
動的ビューを使用したきめ細かなアクセス制御は、 シングル ユーザー アクセス モードのクラスターでは使用できません。
Unity Catalog では、ビュー内の行、列、またはレコードにアクセスできるユーザーを動的に制限できる次の関数が導入されています。
current_user()
: 現在のユーザーの Eメール アドレスを返します。is_account_group_member()
: 現在のユーザーが特定のアカウントレベルのグループのメンバーである場合にTRUE
を返します。 Unity Catalog データに対する動的ビューでの使用をお勧めします。is_member()
: 現在のユーザーが特定のワークスペース レベルのグループのメンバーである場合にTRUE
を返します。 この関数は、既存の Hive metastoreとの互換性のために提供されています。 Unity Catalog データに対するビューでは、アカウントレベルのグループメンバーシップを評価しないため、使用しないでください。
Databricks では、ビューで参照されているテーブルとビューを読み取る機能をユーザーに付与しないことをお勧めします。
次の例は、 Unity Catalogでダイナミックビューを作成する方法を示しています。
列レベルの権限
動的ビューを使用すると、特定のユーザーまたはグループがアクセスできる列を制限できます。 次の例では、 auditors
グループのメンバーのみが sales_raw
テーブルから Eメール アドレスにアクセスできます。 クエリー分析中に、Apache Spark は CASE
ステートメントをリテラル文字列 REDACTED
または Eメール アドレス列の実際の内容に置き換えます。 他の列は通常どおり返されます。 この戦略は、クエリー のパフォーマンスに悪影響を与えません。
-- 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
# 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")
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 = ""))
// 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")
行レベルの権限
動的ビューでは、行レベルまたはフィールド レベルまで権限を指定できます。 次の例では、 managers
グループのメンバーのみが $1,000,000 を超えたときにトランザクション金額を表示できます。 一致する結果は、他のユーザーに対して除外されます。
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;
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")
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 = ""))
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 Catalog のビューは Spark SQL を使用するため、より複雑な SQL 式と正規表現を使用して高度なデータマスキングを実装できます。次の例では、すべてのユーザーが Eメール ドメインを分析できますが、 auditors
グループのメンバーのみがユーザーの Eメール アドレス全体を表示できます。
-- 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
# 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")
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 = ""))
// 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;