ビューの作成

この記事では、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;

次の手順