Databricksレイクハウスにおけるデータオブジェクト

[Data objects in the Databricks Lakehouse \| Databricks on AWS](https://docs.databricks.com/lakehouse/data-objects.html) [2022/8/29]時点の翻訳に一部加筆したものです。

> [Databricksクイックスタートガイド](https://qiita.com/taka_yayoi/items/125231c126a602693610)のコンテンツです。

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

Databricksレイクハウスでは、データベース、テーブル、ビューのように馴染み深いリレーションを用いて、クラウドオブジェクトストレージ上のDelta Lakeに格納されているデータを整理します。このモデルは、データレイクのスケーラビリティと柔軟性とデータウェアハスの数多くのメリットを組み合わせるものです。このモデルがどのように動作するのか、オブジェクトデータとメタデータの関係性を学ぶことで、皆様の企業でDatabricksレイクハウスを設計、実装する際に、ベストプラクティスを適用できるようにしましょう。

# Databricksレイクハウスのデータオブジェクトには何がありますか？

Databricksレイクハウスアーキテクチャは、クラウドストレージにDelta Lakeプロトコルを用いて格納されているデータと、[メタストア](#メタストアとは何ですか)に登録されているメタデータを組み合わせます。Databricksレイクハウスには5つの主要なオブジェクトが存在します。

- **[カタログ](#カタログとは何ですか)**: データベースのグルーピング。
- **[データベース](#データベースとは何ですか)あるいはスキーマ**: カタログにおけるオブジェクトのグルーピング。データベースにはテーブル、ビュー、ファンクションが格納されます。
- **[テーブル](#テーブルとは何ですか)**: オブジェクトストレージのデータファイルとして格納される行と列のコレクション。
- **[ビュー](#ビューとは何ですか)**: 1つ以上のテーブル、データソースに対する保存済みクエリー。 
- **[ファンクション](#ファンクションとは何ですか)**: スカラー値や行セットを返却する保存済みロジック。

![](https://docs.databricks.com/_images/object-model.png)

Unity Catalogにおける保護可能オブジェクトに関しては、[保護可能オブジェクトモデル](https://qiita.com/taka_yayoi/items/065706136dcd2ad9df33#%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%83%A2%E3%83%87%E3%83%AB)をご覧ください。

# メタストアとは何ですか？

メタストアには、レイクハウスのデータオブジェクトを定義するすべてのメタデータが格納されています。Databricksでは以下のメタストアの選択肢を提供しています。

- [**Unity Catalog**](https://docs.databricks.com/data-governance/unity-catalog/create-metastore.html): 格納するためのメタストアを作成し、複数のDatabricksワークスペースでメタデータを共有することができます。Unity Catalogはアカウントレベルで管理されます。
- **Hiveメタストア**: Databricksでは、マネージドサービスとしてビルトインのHiveメタストアにすべてのメタデータを格納します。メタストアのインスタンスはそれぞれのクラスターにデプロイされ、それぞれのお客さまのワークスペースごとに集中管理されたリポジトリからセキュアにメタデータにアクセスすることができます。 
- [**外部メタストア**](https://docs.databricks.com/data/metastores/index.html): ご自身でお使いのメタストアをDatabricksに持ち込むこともできます。

使用するメタストアに関係なく、Databricksではお客様のクラウドアカウントで設定されたオブジェクトストレージにテーブルに関連づけられるすべてのデータを格納します。

# カタログとは何ですか？

カタログはDatabricksのリレーショナルモデルにおける最高位の(あるいは最も粗い)抽象概念です。すべてのデータベースはカタログに関連づけられます。カタログはメタストア内のオブジェクトとして存在します。

Unity Catalogの導入前は、Databricksでは2階層の名前空間を使用していました。Unity Catalogの名前空間モデルでは、カタログは三番目の層になります。

```
catalog_name.database_name.table_name
```

ビルトインのHiveメタストアは単体のカタログ`hive_metastore`のみをサポートします。

# データベースとは何ですか？

データベースはテーブルやビュー(`リレーション`とも呼ばれるものです)、ファンクションのようなデータオブジェクトのコレクションです。(多くのリレーショナルシステムではデータベースはスキーマのコレクションですが)Databricksでは`スキーマ`と`データベース`という単語は同じ意味で使用されます。

データベースは常にクラウドオブジェクトストレージ上の格納場所と関連づけられます。以下のことに留意していただきつつ、データベースを作成する際にオプションで`LOCATION`を指定することができます。

- データベースに関連づけられる`LOCATION`は常に(データベースによって管理される)マネージドの格納場所と見做されます。
- データベースの作成自体はターゲットの格納場所にいかなるファイルも作成しません。
- データベースの`LOCATION`は当該データベースに登録されるすべてのテーブルのデータのデフォルトの格納場所を決定します。
- データベースの削除に成功すると、マネージドの格納場所にあるすべてのデータとファイルは再帰的に削除されます。

データベースによって管理される格納場所とデータファイルの間のやりとりは非常に重要なものとなります。間違ってデータを削除しないようにするには：

- 複数のデータベース定義でデータベースの格納場所を共有しないでください。
- すでにデータが格納されている格納場所にデータベースを作成しないでください。
- データベースと独立してデータのライフサイクルを管理するには、いかなるデータベースの格納場所に含まれない場所にデータを保存してください。

# テーブルとは何ですか？

Databricksのテーブルは構造化データのコレクションです。Deltaテーブルはデータをクラウドオプジェクトストレージ上のファイルのディレクトリとして格納し、テーブルのメタデータをカタログ、スキーマ内のメタストアに登録します。Delta LakeはDatabricksで作成されるテーブルのデフォルトのストレージプロバイダーなので、Databricksで作成されるすべてのテーブルはデフォルトではDeltaテーブルになります。Deltaテーブルはデータをクラウドオブジェクトストレージに格納し、メタストアを通じてデータへのリファレンスを提供するので、企業のユーザーは好みのAPI(DatabricksにおいてはSQL、Python、PySpark、Scala、R)を用いてデータにアクセスすることができます。

Databricksでは、Deltaテーブルではないテーブルも作成できることに注意してください。これらのテーブルはDelta Lakeによるサポートがないため、DeltaテーブルのACIDトランザクションや最適化されたパフォーマンスを提供することはできません。このカテゴリーに該当するテーブルには、[外部システム](https://docs.databricks.com/data/data-sources/index.html)に存在するデータに対して登録されたテーブル、[データレイクにおける他のファイルフォーマット](https://docs.databricks.com/data/data-sources/index.html)に対して登録されたテーブルが含まれます。

Databricksには2種類のテーブルがあります。[マネージド](#マネージドテーブルとは何ですか)と[アンマネージド](#アンマネージドテーブルとは何ですか)(外部)テーブルです。

:::note info
**注意**
[Delta Live Tables](#delta-live-tablesではリレーショナルオブジェクトはどのように動作しますか)におけるliveテーブルとストリーミングliveテーブルの区別は、ここでのテーブルの観点では強制されません。
:::

## マネージドテーブルとは何ですか？

Databricksでは、マネージドテーブルのメタデータとデータの両方を管理します。テーブルを削除すると、背後にあるデータも削除することになります。SQLを使うデータアナリストや他のユーザーは、多くの場合この挙動を好むことでしょう。テーブルを作成する際、デフォルトはマネージドテーブルになります。マネージドテーブルのデータは、登録されるデータベースの`LOCATION`に存在することになります。このデータの格納場所とデータベース間のマネージドの関係性は、マネージドテーブルを新たなデータベースに移動するには、すべてのデータを新たな場所に再度書き込まなくてはならないことを意味します。

以下のように、マネージドテーブルを作成する方法は数多く存在します。

```sql:SQL
CREATE TABLE table_name AS SELECT * FROM another_table
```

```sql:SQL
CREATE TABLE table_name (field_name1 INT, field_name2 STRING)
```

```py:Python
df.write.saveAsTable("table_name")
```

## アンマネージドテーブルとは何ですか？

Databricksでは、アンマネージド(外部)テーブルのメタデータのみを管理します。テーブルを削除した際、背後のデータは影響を受けません。アンマネージドテーブルでは、テーブル作成の際に常に`LOCATION`を指定します。既存のデータファイルのディレクトリをテーブルとして登録したり、テーブルを最初に定義する際にパスを指定することができます。データとメタデータは独立に管理されるので、いかなるデータを移動することなしに、テーブル名を変更したり、新たなデータベースに登録したりすることができます。多くの場合、データエンジニアはアンマネージドテーブルを好み、プロダクションデータのためにこれらが提供する柔軟性を好みます。

以下のように、アンマネージドテーブルを作成する方法は数多く存在します。

```sql:SQL
CREATE TABLE table_name
USING DELTA
LOCATION '/path/to/existing/data'
```

```sql:SQL
CREATE TABLE table_name
(field_name1 INT, field_name2 STRING)
LOCATION '/path/to/empty/directory'
```

```py:Python
df.write.option("path", "/path/to/empty/directory").saveAsTable("table_name")
```

:::note info
**訳者追記**
マネージドテーブルとアンマネージドテーブルの違いをまとめた表です。
:::

|  | マネージドテーブル | アンマネージド(外部)テーブル |
|:--|:--|:--|
| 作成方法  | テーブル作成時に`LOCATION`を指定しない  | テーブル作成時に`LOCATION`を指定する  |
| データファイルの格納場所  | データベースが`LOCATION`指定で作成されている場合には、`LOCATION`配下。データベースに`LOCATION`が指定されていない場合には、`/user/hive/warehouse`配下(Hiveメタストアの場合)  | 指定した`LOCATION`配下  |
| メリット  | 取り扱いが楽(DROP TABLEでデータも削除できる)  | データの格納場所を柔軟に制御できる(特殊なセキュリティ保護がされたストレージに作成できるなど)  |
| デメリット  | 柔軟性に欠ける(自分でデータの格納場所を制御できない)  | 取り回しが若干面倒  |

# ビューとは何ですか？

ビューは通常、1つ以上のデータソースあるいはメタストアのテーブルに対するクエリーのテキストを保存します。Databricksでは、ビューはデータベースのオブジェクトとして永続化されるSparkデータフレームと等価です。データフレームと異なり、アクセス権がある限り、いかなるDatabricks製品の一部からビューにクエリーを実行することができます。ビューの作成自体はいかなるデータの処理、書き込みを行いません。クエリーのテキストが関連づけられているデータベースのメタストアに登録されるのみです。

# 一時ビューとは何ですか？

一時ビューには限定的なスコープと永続性があり、スキーマやカタログには登録されません。一時ビューの寿命は使用している環境によって異なります。

- ノートブックやジョブでは、一時ビューはノートブックあるいはスクリプトレベルとなります。宣言されたノートブックの外から参照することはできず、ノートブックがクラスターからデタッチされると存在しなくなります。
- Databricks SQLでは、ビューはクエリーレベルのスコープとなります。同じクエリー内の複数の文は一時ビューを使用できますが、同じダッシュボードであったとしても、別のクエリーから一時ビューを参照することはできません。
- グローバル一時ビューはクラスターレベルであり、計算リソースを共有するノートブックやジョブで共有することができます。グローバル一時ビューの代わりに適切なテーブルACL(アクセスコントロールリスト)が適用されたビューを使用することをお勧めします。

:::note info
**訳者追記**
テーブル、ビュー、一時ビュー、グローバル一時ビューの違いをまとめた表です。
:::

|  | テーブル | ビュー | 一時ビュー | グローバル一時ビュー |
|:--|:--|:--|:--|:--|
| クラスターを停止しても永続化されるか  |  YES | YES  | NO  | NO  |
| 同じクラスターに接続している他のユーザーと共有できるか  | YES  |  YES | NO  | YES  |
| 別のクラスターに接続している他のユーザーと共有できるか  |  YES | YES  | NO  | NO  |
| データを更新できるか  |  YES | NO  | NO  | NO  |
| アクセス権を設定できるか  |  YES | YES  | NO  | NO  |

# ファンクションとは何ですか？

ファンクションを用いることで、データベースとユーザー定義ロジックを関連づけることができます。ファンクションはスカラー値あるいは行セットを返却することができます。Databricks製品におけるさまざまな文脈におけるカスタムロジックに対するアクセスを管理するためにファンクションを活用することができます。

# Delta Live Tablesではリレーショナルオブジェクトはどのように動作しますか？

[Delta Live Tables](https://docs.databricks.com/data-engineering/delta-live-tables/index.html)は、DDL、DML、インフラストラクチャのデプロイメントを定義、管理するための宣言型構文を使用します。Delta Live Tablesはロジックの計画と実行時に`仮想的スキーマ`のコンセプトを使用します。Delta Live Tablesはお使いのDatabricks環境の他のデータベースとやり取りをすることができ、Delta Live Tablesではパイプライン設定でターゲットデータベースを指定することで、どこからでもクエリーできるようにテーブルを公開・永続化することができます。Delta Live Tablesで作成されたすべてのテーブルはDeltaテーブルであり、マネージドテーブルあるいはアンマネージドテーブルとして宣言することができます。

Delta Live Tablesでビューを宣言することはできますが、これらはパイプラインスコープの一時ビューと考えるべきです。Delta Live Tablesにおける一時テーブルはユニークなコンセプトです：これらのテーブルはストレージに永続化されますが、ターゲットデータベースには公開されません。

`APPLY CHANGES INTO`のようないくつかのオペレーションは、テーブルとビューの両方をデータベースに登録します。テーブル名はアンダースコア(`_`)で始まり、ビューには`APPLY CHANGES INTO`オペレーションのターゲットとして宣言されたテーブル名が含まれます。このビューは、結果をマテリアライズするために隠しテーブルに対応するクエリーを実行します。

### Databricks 無料トライアル

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