Unity Catalogのカタログの作成と管理

[Create and manage catalogs \| Databricks on AWS](https://docs.databricks.com/data-governance/unity-catalog/create-catalogs.html) [2023/6/8時点]の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

本書では、Unity Catalogにおけるカタログの作成、管理方法を説明します。カタログには[スキーマ(データベース)](https://docs.databricks.com/data-governance/unity-catalog/create-schemas.html)が含まれ、スキーマにはテーブルとビューが含まれます。

# 要件

- あなたがDatabricksメタストア管理者であるか、メタストアに対する`CREATE CATALOG`権限を付与されていること。
- お使いのDatabricksアカウントがPremiumプラン以上であること。
- カタログ作成を行う[ワークスペースにUnity Catalogメタストアがリンク](https://docs.databricks.com/data-governance/unity-catalog/create-metastore.html)されていること。
- カタログを作成するためのノートブックやDatabricks SQLを実行する[計算リソース](https://docs.databricks.com/data-governance/unity-catalog/compute.html)は、Unity Catalog互換のアクセスモードを用いてること。

# カタログの作成

カタログを作成するには、データエクスプローラかSQLコマンドを使用できます。

## データエクスプローラ

1. メタストアにリンクされているワークスペースにログインします。
1. ![](https://docs.databricks.com/_images/data-icon.png)**Data**をクリックします。
1. **Create Catalog**ボタンをクリックします。
1. (オプション)カタログの[マネージドテーブル](https://qiita.com/taka_yayoi/items/f23b9ee50c453bb8f8a8#%E3%83%9E%E3%83%8D%E3%83%BC%E3%82%B8%E3%83%89%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB)のデータが格納されるロケーションを指定します。

    メタストアで設定されたデフォルトのルートストレージロケーションにこのカタログのマネージドテーブルを格納したくない場合にのみ、ここでロケーションを指定します。[Create a Unity Catalog metastore](https://docs.databricks.com/data-governance/unity-catalog/create-metastore.html)をご覧ください。
    
    指定するパスは、外部ロケーション設定で定義されている必要があり、その外部ロケーションに対する`CREATE MANAGED STORAGE`権限を持っている必要があります。また、そのパスのサブパスを使用することもできます。[Unity Catalogにおける外部ロケーションとストレージ認証情報の管理](https://qiita.com/taka_yayoi/items/18fee92365eee58e0b94)をご覧ください。

1. **Create**をクリックします。
1. (オプション)カタログが紐付けられるワークスペースを指定します。

    デフォルトでは、カタログは現在のメタストアにアタッチされているすべてのワークスペースで共有されます。カタログに特定のワークスペースに制限すべきデータが含まれている場合は、**Workspaces**タブに移動して、それらのワークスペースを追加します。

    詳細は、[(オプション)特定のワークスペースへのカタログの割り当て](#オプション特定のワークスペースへのカタログの割り当て)をご覧ください。
1. カタログのアクセス権を割り当てます。[Unity Catalogにおける権限およびセキュリティ保護可能オブジェクト](https://qiita.com/taka_yayoi/items/57dfb4d1c5908c1f5d9e)をご覧ください。

カタログを作成すると、`default`と`information_schema`の2つのスキーマ(データベース)が自動的に作成されます。

また、[Databricks Terraform provider](https://docs.databricks.com/dev-tools/terraform/index.html)と[databricks\_catalog](https://registry.terraform.io/providers/databricks/databricks/latest/docs/resources/catalog)を用いることでカタログを作成することができます。[databricks\_catalogs](https://registry.terraform.io/providers/databricks/databricks/latest/docs/data-sources/catalogs)を用いることで、カタログに関する情報を取得することができます。

## SQL

1. ノートブックかSQLエディタで以下のSQLコマンドを実行します。大括弧内のアイテムはオプションです。以下のプレースホルダーを置き換えてください:
    - `<catalog-name>`: カタログ名。
    - `<location-path>`: オプション。メタストアで設定されたデフォルトのルートストレージロケーションにこのカタログのマネージドテーブルを格納したくない場合に、ロケーションを指定します。このパスは[外部ロケーション設定](https://qiita.com/taka_yayoi/items/18fee92365eee58e0b94)で定義され、この外部ロケーション設定に対する`CREATE MANAGED STORAGE`権限を持っっている必要があります。外部ロケーションで定義されているパスやるいはサブパス(言い換えると、`'s3://depts/finance'`や`'s3://depts/finance/product'`)を使用することができます。Databricksランタイム11.3以降が必要です。
    - `<comment>`: オプションのコメント。

    ```sql
    CREATE CATALOG [ IF NOT EXISTS ] <catalog-name>
       [ MANAGED LOCATION '<location-path>' ]
       [ COMMENT <comment> ];
    ```

    例えば、`example`というカタログを作成するには:

    ```sql
    CREATE CATALOG IF NOT EXISTS example;
    ```

1. カタログに権限を割り当てます。[Unity Catalogにおける権限およびセキュリティ保護可能オブジェクト](https://qiita.com/taka_yayoi/items/57dfb4d1c5908c1f5d9e)をご覧ください。

## Python

```py
spark.sql("CREATE CATALOG [ IF NOT EXISTS ] <catalog-name> [ MANAGED LOCATION '<location-path>' ] [ COMMENT <comment> ]")
```
```py
spark.sql("CREATE CATALOG IF NOT EXISTS example")
```

## R

```r
library(SparkR)

sql("CREATE CATALOG [ IF NOT EXISTS ] <catalog-name> [ MANAGED LOCATION '<location-path>' ] [ COMMENT <comment> ]")
```

```r
library(SparkR)

sql("CREATE CATALOG IF NOT EXISTS example")
```

## Scala

```scala
spark.sql("CREATE CATALOG [ IF NOT EXISTS ] <catalog-name> [ MANAGED LOCATION '<location-path>' ] [ COMMENT <comment> ]")
```

```scala
spark.sql("CREATE CATALOG IF NOT EXISTS example")
```

# (オプション)特定のワークスペースへのカタログの割り当て

ユーザーのデータアクセスを分離するためにワークスペースを使い場合、カタログへのアクセスをお使いのアカウントの特定のワークスペースに限定したいと考え、ワークスペース・カタログバインディングと呼ばれる機能を使いたいと考えるかもしれません。デフォルトでは、現在のメタストアにアタッチされたすべてのワークスペースでカタログは共有されます。

カタログを特定のワークスペースにバインディングする典型的なユースケースには以下のようなものがあります:

- プロダクションのワークスペース環境からのユーザーのみがプロダクションデータにアクセスするようにする。
- 専用ワークスペースからのユーザーのみセンシティブなデータにアクセスできるようにする。

プロダクションと開発の分離の例を取ります。お使いのプロダクションデータカタログはプロダクションワークスペースからのみアクセスできることを指定した場合、これは、ユーザーに発行されている個人の権限を上書きします。
![](https://docs.databricks.com/_images/catalog-bindings.png)

この図では、`prod_catalog`は2つのプロダクションワークスペースにバインディングされています。(`GRANT SELECT ON my_table TO <user>`を用いて)あるユーザーに、`prod_catalog`の`my_table`と呼ばれるテーブルへのアクセスが許可されているものとします。Devワークスペースでこのユーザーが`my_table`にアクセスしようとすると、エラーメッセージを受け取ります。このユーザーはProd ETLかProd Analyticsワークスペースからのみ`my_table`にアクセスすることができます。

ワークスペース・カタログバインディングは、プラットフォームのすべての領域で考慮されます。例えば、information schemaをクエリーする際、クエリーを実行したワークスペースからアクセスできるカタログのみを参照できます。データリネージや検索UIなどは、(バインディングを使っていようがデフォルトであろうが)ワークスペースに割り当てられてるカタログのみを表示します。

## 設定

特定のワークスペースにカタログを割り当てるには、データエクスプローラかUnity Catalog REST APIを使用することができます。

**必要な権限:** メタストア管理者あるいはカタログオーナー。

:::note
**注意**
メタストア管理者は、カタログが現在のワークスペースに割り当てられているかどうかに関係なく、データエクスプローラを用いてメタストアのすべてのカタログを参照することができます。そして、カタログオーナーは、メタストアで所有しているすべてのカタログを参照することができます。ワークスペースに割り当てられていないカタログはグレー表示され、子供のオブジェクトを参照したりクエリーすることはできません。
:::

### データエクスプローラ

1. メタストアにリンクされているワークスペースにログインします。
1. ![](https://docs.databricks.com/_images/data-icon.png)**Data**をクリックします。
1. **Data**ペインの左でカタログ名をクリックします。

    メインのデータエクスプローラのペインはデフォルトでは**Catalogs**リストです。そこでもカタログを選択することができます。

1. **Workspaces**タブで、**All workspaces have access**チェックボックスをクリアします。
1. **Assign to workspaces**をクリックし、割り当てたいワークスペースを入力あるいは検索します。

アクセスを取り消すには、**Workspaces**タブでワークスペースを選択して**Revoke**をクリックします。

### API

カタログをワークスペースに割り当てるのに必要な2つのAPIと2つのステップが存在します。以下の例では、`<workspace-url>`をワークスペースのインスタンス名に置き換えてください。ワークスペースインスタンス名やワークスペースIDの取得方法については、[DatabricksでワークスペースID、クラスターID、ノートブックID、モデルID、ジョブIDを取得する](https://qiita.com/taka_yayoi/items/7127cabac70dd994fcba)をご覧ください。アクセストークンの取得方法については、[Databricks自動化における認証処理](https://qiita.com/taka_yayoi/items/f5493a4169e95e1a7a61)をご覧ください。

1. カタログの`isolation mode`を`ISOLATED`に設定するために`catalogs` APIを使います:

    ```bash
    curl -L -X PATCH 'https://<workspace-url>/api/2.1/unity-catalog/catalogs/<my-catalog> \
    -H 'Authorization: Bearer <my-token> \
    -H 'Content-Type: application/json' \
    --data-raw '{
     "isolation_mode": "ISOLATED"
     }'
    ```

    デフォルトの`isolation mode`は、メタストアにアタッチされているすべてのワークスペースに対する`OPEN`です。

1. カタログにワークスペースを割り当てるために`workspace-bindings` APIを使います:

    ```bash
    curl -L -X PATCH 'https://<workspace-url>/api/2.1/unity-catalog/workspace-bindings/catalogs/<my-catalog> \
    -H 'Authorization: Bearer <my-token> \
    -H 'Content-Type: application/json' \
    --data-raw '{
      "assign_workspaces": [<workspace-id>, <workspace-id2>],
      "unassign_workspaces": [<workspace-id>, <workspace-id2>]
    }'
    ```

カタログに割り当てられているすべてのワークスペースを一覧するには、`workspace-bindings` APIを使います:

```bash
   curl -L -X PATCH 'https://<workspace-url>/api/2.1/unity-catalog/workspace-bindings/catalogs/<my-catalog> \
   -H 'Authorization: Bearer <my-token> \
```

## 次のステップ

[add schemas \(databases\) to your catalog](https://docs.databricks.com/data-governance/unity-catalog/create-schemas.html)を行うことができます。

# カタログの削除

カタログを削除(ドロップ)するには、データエクスプローラかSQLコマンドを使用することができます。

## データエクスプローラ

カタログを削除する前に`information_schema`を除くカタログ内のすべてのスキーマを削除する必要があります。

1. メタストアにリンクされているワークスペースにログインします。
1. ![](https://docs.databricks.com/_images/data-icon.png)**Data**をクリックします。
1. **Data**ペインの左で削除したいカタログ名をクリックします。
1. 詳細ペインで、**Create database**ボタンの左の3点メニューをクリックし、**Delete**を選択します。
1. **Delete catalog**ダイアログで**Delete**をクリックします。

## SQL

以下のSQLコマンドをノートブックかSQLエディタで実行します。大括弧内のアイテムはオプションです。プレースホルダー`<catalog-name>`を置き換えてください。

パラメーターの説明に関しては、[DROP CATALOG](https://docs.databricks.com/sql/language-manual/sql-ref-syntax-ddl-drop-catalog.html)をご覧ください。

`CASCADE`オプションなしで`DROP CATALOG`を使う場合、カタログを削除する前に`information_schema`以外のカタログのすべてのスキーマを削除しなくてはなりません。これには、自動生成された`default`スキーマも含まれます。

```sql
DROP CATALOG [ IF EXISTS ] <catalog-name> [ RESTRICT | CASCADE ]
```

例えば、カタログ`vaccine`とそのスキーマを削除するには:

```sql
DROP CATALOG vaccine CASCADE
```

## Python

```py
spark.sql("DROP CATALOG [ IF EXISTS ] <catalog-name> [ RESTRICT | CASCADE ]")
```
```py
spark.sql("DROP CATALOG vaccine CASCADE")
```

## R

```r
library(SparkR)

sql("DROP CATALOG [ IF EXISTS ] <catalog-name> [ RESTRICT | CASCADE ]")
```

```r
library(SparkR)

sql("DROP CATALOG vaccine CASCADE")
```

## Scala

```scala
spark.sql("DROP CATALOG [ IF EXISTS ] <catalog-name> [ RESTRICT | CASCADE ]")
```
```scala
spark.sql("DROP CATALOG vaccine CASCADE")
```


### Databricksクイックスタートガイド

[Databricksクイックスタートガイド](https://www.amazon.co.jp/dp/B09V1YXFVQ/)


### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)