Unity CatalogとレガシーHiveメタストアを操作する

[Work with Unity Catalog and the legacy Hive metastore \| Databricks on AWS](https://docs.databricks.com/data-governance/unity-catalog/hive-metastore.html) [2022/8/26時点]の翻訳です。

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

# Unity CatalogにおけるHiveメタストアへのクエリー

Unity Catalogは追加可能なものであるので、DatabricksにおけるワークスペースごとのHiveメタストアと一緒に使用できることを意味します。Hiveメタストアは3レベルの名前空間の`hive_metastore`として表示されます。

例えば、以下の記述を用いることでレガシーのHiveメタストアの`schema`の`sales_raw`と呼ばれるテーブルを参照することができます。

```sql:SQL
SELECT * from hive_metastore.sales.sales_raw;
```

```py:Python
display(spark.table("hive_metastore.sales.sales_raw"))
```

```r:R
library(SparkR)

display(tableToDF("hive_metastore.sales.sales_raw"))
```

```scala:Scala
display(spark.table("hive_metastore.sales.sales_raw"))
```

また、`USE`文を使ってカタログやスキーマを指定することができます。

```sql:SQL
USE hive_metastore.sales;
SELECT * from sales_raw;
```

```py:Python
spark.sql("USE hive_metastore.sales")
display(spark.table("sales_raw"))
```

```r:R
library(SparkR)

sql("USE hive_metastore.sales")
display(tableToDF("sales_raw"))
```

```scala:Scala
spark.sql("USE hive_metastore.sales")
display(spark.table("sales_raw"))
```

# Unity CatalogとHiveメタストアのアクセスコントロール

Hiveメタストアで[テーブルアクセスコントロール](https://docs.databricks.com/security/access-control/table-acls/index.html)を設定している場合、共有アクセスモードで稼働しているクラスターにおいては、Databricksは`hive_metastore`のデータに対してこれらのアクセスコントロールを強制し続けます。Unity Catalogのアクセスモデルは、`DENY`文が無いなどレガシーなアクセスコントロールとは若干異なります。`hive_metastore`カタログで定義されたアクセス権は、常にワークスペースのローカルユーザーとグループを参照します。[テーブルアクセスコントロールとの違い](#テーブルアクセスコントロールとの違い)をご覧ください。

# テーブルアクセスコントロールとの違い

Unity CatalogはワークスペースごとのレガシーなHiveメタストアで[テーブルアクセスコントロール](https://docs.databricks.com/security/access-control/table-acls/index.html)を用いることと、以下のキーとなる違いがあります。

Unity Catalogにおけるアクセスコントロールモデルは、テーブルアクセスコントロールと以下の点で異なります。

- **アカウントレベルのアイデンティティ:** Unity Catalogにおけるアクセスコントロールポリシーは、アカウントレベルのユーザーやグループに適用されます。Hiveメタストアのアクセスコントロールポリシーはワークスペースレベルのユーザーとグループに適用されます。
- **権限の継承はありません:** Unity Catalogでは親のオブジェクトの権限は、子供のオブジェクトには継承されません。
- **カタログ内のオブジェクトに対するすべてのオペレーションにおいては、カタログにおける`USAGE`権限が必要です:** テーブルやデータベースのプリンシパルの権限に関係なく、テーブルやデータベースにアクセスするためにはプリンシパルに`USAGE`権限が必要となります。ワークスペースレベルのテーブルアクセスコントロールを用いることで、ルートカタログに`USAGE`を許可するとすべてのデータベースに対して`USAGE`が自動で許可されますが、ルートカタログの`USAGE`は不要です。
- **ビュー:** Unity Catalogでは、ビューのオーナーはビューが参照するテーブルやビューのオーナーである必要がありません。ビューの親のスキーマ、カタログの`USAGE`と`SELECT`権限で十分です。ワークスペースレベルのテーブルアクセスコントロールを用いる際には、ビューのオーナーは参照するすべてのテーブルとビューのオーナーである必要があります。
- **`ALL FILES`や`ANONYMOUS FUNCTION`のサポートはありません:** Unity Catalogでは、`ALL FILES`や`ANONYMOUS FUNCTION`権限の概念がありません。これらの権限は許可されないユーザーが許可されたコードを実行できるように、アクセスコントロールの制限を回避するために使用される可能性があります。

# Unity CatalogとHiveメタストアオブジェクトのJoin

3レベルの名前空間の記述を用いることで、Unity CatalogのメタストアとレガシーHiveメタストアのjoinを行うことができます。

:::note info
**注意**
レガシーHiveのデータとのjoinは、データが存在しているワークスペースでのみ動作します。他のワークスペースでのこのようなjoinを実行しようとするとエラーとなります。レガシーなテーブルとビューをUnity Catalogに[アップグレード](https://qiita.com/taka_yayoi/items/5e896b50b915b9de8fb3)することをお勧めします。
:::

以下の例では、レガシーなHiveメタストアの`sales_current`テーブルと、Unity Catalogの`sales_historical`テーブルで、`order_id`フィールドが等しい場合にjoinしています。

```sql:SQL
SELECT * FROM hive_metastore.sales.sales_current
JOIN main.shared_sales.sales_historical
ON hive_metastore.sales.sales_current.order_id = main.shared_sales.sales_historical.order_id;
```

```py:Python
dfCurrent = spark.table("hive_metastore.sales.sales_current")
dfHistorical = spark.table("main.shared_sales.sales_historical")

display(dfCurrent.join(
  other = dfHistorical,
  on = dfCurrent.order_id == dfHistorical.order_id
))
```

```r:R
library(SparkR)

dfCurrent = tableToDF("hive_metastore.sales.sales_current")
dfHistorical = tableToDF("main.shared_sales.sales_historical")

display(join(
  x = dfCurrent,
  y = dfHistorical,
  joinExpr = dfCurrent$order_id == dfHistorical$order_id))
```

```scala:Scala
val dfCurrent = spark.table("hive_metastore.sales.sales_current")
val dfHistorical = spark.table("main.shared_sales.sales_historical")

display(dfCurrent.join(
  right = dfHistorical,
  joinExprs = dfCurrent("order_id") === dfHistorical("order_id")
))
```

# デフォルトカタログ

トップレベルのカタログ名を省略し、`USE CATALOG`文を使用しない場合、デフォルトのカタログが仮定されます。ワークスペースのデフォルトカタログを設定するには、`spark.databricks.sql.initial.catalog.name`の値を設定します。

変更なしに既存のコードが現在のHiveメタストアを操作できるように、デフォルトのカタログの値は`hive_metastore`に設定することをお勧めします。

# クラスターのインスタンスプロファイル

Unity CatalogとHiveメタストアを一緒に使用する際、クラスターのインスタンスプロファイルは、Hiveメタストアのデータにアクセスするために使用されますが、Unity Catalogに登録されているデータには使用されません。

ユーザーがUnity Catalogの外のパス(テーブルとして登録されていないパスや外部ロケーションなど)にアクセスすると、クラスターのインスタンスプロファイルが使用されます。

# レガシーテーブルをUnity Catalogにアップグレードする

Hiveメタストアのテーブルは、Unity Catalogが導入するビルトインの監査やアクセスコントロールのようなセキュリティやガバナンスのフル機能を活用することができません。これらをUnity Catalogに追加することで[レガシーテーブルをアップグレード](https://qiita.com/taka_yayoi/items/5e896b50b915b9de8fb3)することをお勧めします。

### Databricks 無料トライアル

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