ビューの作成
この記事では、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;
Note
ビューが Delta テーブル以外のデータ ソースによってバックアップされている場合、ビューの実行セマンティクスが異なる場合があります。 Databricks では、常にテーブル名またはビュー名を使用してデータ ソースを参照することで、ビューを定義することをお勧めします。 パスまたは URI を指定してデータセットに対してビューを定義すると、データ ガバナンス要件が混乱する可能性があります。
要件
ビューを作成するには:
- 親カタログに対する
USE CATALOG
のアクセス許可と、親スキーマに対するUSE SCHEMA
およびCREATE TABLE
のアクセス許可が必要です。 メタストア管理者またはカタログ所有者は、これらすべての権限を許可できます。 スキーマ所有者は、スキーマに対するUSE SCHEMA
およびCREATE TABLE
権限を付与できます。 - ビューで参照されるテーブルとビューを読み取れる必要があります (テーブルまたはビューでの
SELECT
、カタログでのUSE CATALOG
、スキーマでのUSE SCHEMA
)。 - ビューがワークスペース ローカルの Hive メタストア内のテーブルを参照している場合、そのビューにアクセスできるのは、ワークスペース ローカル テーブルが含まれるワークスペースからに限られます。 このため、Databricks では、Unity Catalog メタストア内にあるテーブルまたはビューからのみビューを作成することをお勧めします。
- Delta Sharing を使用して自分と共有されているビューを参照するビューを作成することはできません。 「Delta Sharing を使用してデータと AI 資産を安全に共有する」を参照してください。
ビューを読み取るために必要なアクセス許可は、クラスター アクセス モードによって異なります。
- 共有クラスターの場合は、ビュー自体に
SELECT
、その親カタログにUSE CATALOG
、その親スキーマにUSE SCHEMA
が必要です。 - シングルユーザー クラスターの場合は、親カタログの
USE CATALOG
とその親スキーマのUSE SCHEMA
に加えて、ビューが参照するすべてのテーブルとビューにSELECT
も必要です。
シングルユーザー クラスターを使用して動的ビューを作成または読み取ることはできません。
ビューの作成
ビューを作成するには、次の 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 Catalog では、動的ビューを使用して、次のようにアクセス制御をきめ細かく構成できます。
- 列または行のレベルでのセキュリティ。
- データ マスキング。
注意
動的ビューを使用したきめ細かいアクセス制御は、単一ユーザー アクセス モードのクラスターでは使用できません。
Unity Catalog には次の機能が導入されています。これにより、ビュー内の行、列、またはレコードにアクセスできるユーザーを動的に制限できます。
current_user()
: 現在のユーザーのメールアドレスを返します。is_account_group_member()
: 現在のユーザーが特定のアカウントレベル グループのメンバーである場合は、TRUE
を返します。 Unity Catalog データに対して動的ビューで使用することをお勧めしています。is_member()
: 現在のユーザーが特定のアカウントレベル グループのメンバーである場合は、TRUE
を返します。 この関数は、既存の Hive メタストアとの互換性を提供します。 Unity のカタログ データに対するビューでは使用しないでください。これは、アカウントレベルのグループ メンバーシップを評価しないためです。
Azure Databricks では、ビューで参照されるテーブルとビューを読み取る権限をユーザーに許可しないことをお勧めします。
次に、Unity Catalog で動的ビューを作成する例を示します。
列レベルのアクセス許可
動的ビューでは、特定のユーザーまたはグループがアクセスできる列を制限できます。 次に、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")
行レベルのアクセス許可
動的ビューでは、行またはフィールドのレベルまでの権限を指定できます。 次に、100 万ドルを超えた場合に 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 Catalog のビューでは 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;