Snowflakeのデータ共有機能（Direct Share）の概要理解とハンズオン

Snowflakeのデータ共有(Secure Data Sharing)のDirect Share機能を使ってみましたので紹介です。
公式ドキュメントを読まなくても、とりあえず使ってみれるように最低限のサンプルコードを記載しておきます。Worksheetに貼り付けて使ってみてください。

# 事前に理解しておくこと
## データ共有機能は3つある
まず、データ共有の機能は以下の3つが存在することを理解しておきます。
* Direct Share  
* Snowflake Data Marketplace
* Data Exchange

> Direct Shareは、SnowflakeのSecure Data Sharingを利用して、アカウント間のデータ共有を可能にする最も簡単な形式のデータ共有です。
> [引用元](https://docs.snowflake.com/ja/user-guide/data-sharing-product-offerings.html#direct-share)

この中のDirect Share ([Secure Direct Data Share](https://docs.snowflake.com/ja/user-guide/data-share-providers.html))の紹介になります。要するに知っているアカウントにデータを共有する方法です。

## データプロバイダーとコンシューマーを、ざっくり理解する
次に、データプロバイダーはデータを共有する側、データコンシューマーはデータを共有される側、とざっくり理解しておきます。

> データプロバイダーは、共有を作成し、それらを他のSnowflakeアカウントが利用できるようにするSnowflakeアカウントです。
> [引用元](https://docs.snowflake.com/ja/user-guide/data-sharing-intro.html#providers)

> データコンシューマーは、データプロバイダーにより提供される共有から、データベースの作成を選択したアカウントです。
> [引用元](https://docs.snowflake.com/ja/user-guide/data-sharing-intro.html#consumers)

![Data Sharing Overview](https://docs.snowflake.com/ja/_images/data-sharing-overview.png "Data Sharing Overview")

## データプロバイダーとコンシューマーを、もう少し理解する
コンシューマーが共有されたデータにアクセスする場合は、コンシューマー自身のコンピュートリソース（Warehouse）を利用します。すなわちデータを使うコンシューマーに課金されるってことで、これも良いですね。コンピュート（Warehouse）とストレージ（Database）が分離されているSnowflakeならではではないかと思います。

> Secure Data Sharingにより、アカウント間で実際のデータのコピー、または転送は されません 。すべての共有は、Snowflakeの独自のサービスレイヤーとメタデータストアを介して行われます。これは、共有データがコンシューマーアカウントのストレージを占有しない、つまりコンシューマーの毎月のデータストレージ料金に課金されないことを意味するため、重要な概念です。コンシューマーへの課金は、共有データのクエリに使用されるコンピューティングリソース（つまり、仮想ウェアハウス）に対するもの のみ です。
> [引用元](https://docs.snowflake.com/ja/user-guide/data-sharing-intro.html#how-does-secure-data-sharing-work)

## 共有相手がアカウントを持っていない場合はリーダーアカウントが使えそう
以降のサンプルは、共有したい相手がSnowflakeアカウントを持っていること（準備できること）を前提としたものですが、相手がアカウントを取得できない（または時間がかかる）場合にプロバイダー側が[リーダーアカウント](https://docs.snowflake.com/ja/user-guide/data-sharing-intro.html#reader-accounts)を用意することができます。容易に想定されるケースなので有用そうです。

# Direct Shareの機能をとりあえず使ってみる
事前準備として、データプロバイダー側のアカウントと、データコンシューマー側のアカウントの２つを用意してください。

## データプロバイダー（データを共有する側）でテーブルを共有する
本項は、データプロバイダー側のアカウントでの設定です。

```sql
// 自分の環境に合わせて以下の変数を設定して使うと楽です。
SET db_name = 'TEST_DB';
SET schema_name = 'TEST_SCHEMA';
SET table_name = 'TEST_TABLE';
SET share_name = 'TEST_SHARE'; //
SET account_name = 'TEST_ACCOUNT'; //
```
以下のコードですが、ACCOUNTADMINロールを使用する必要があります。なので、共有の作業自体は楽にできるのですが、データ共有の機能を使いたい場合は高位権限者の理解と協力が必要になります。
```sql
USE ROLE ACCOUNTADMIN;
// Step1: SHAREを作成
CREATE SHARE identifier($share_name);
// Step2: SHAREに以下の3つの権限を付与する
GRANT USAGE ON DATABASE identifier($db_name) TO SHARE identifier($share_name);
GRANT USAGE ON SCHEMA identifier($schema_name) TO SHARE identifier($share_name);
GRANT SELECT ON TABLE identifier($table_name) TO SHARE identifier($share_name);
// Step3: SHAREに1つ以上のアカウントを追加する
ALTER SHARE identifier($share_name) add accounts=identifier($account_name);
```

## データコンシューマー（データを共有される側）で共有されたテーブルを参照する
本項は、データコンシューマー側のアカウントでの設定です。

```sql
SET provider_db_name = 'TEST_PROVIDER_DB';
SET provider_account_share_name = 'TEST_ACCOUNT.TEST_SHARE'; //account_nameとshare_name
SET provider_schema_name = 'TEST_SCHEMA';//schema_nameと同じ
SET provider_table_name = 'TEST_TABLE';//table_name
```
コンシューマー側もACCOUNTADMINロールを使用する必要があります。
共有されたSHAREからデータベースを作成するだけです。簡単。以上！
```sql
USE ACCOUNTADMIN;
CREATE DATABASE identifier($provider_db_name) FROM SHARE identifier($provider_account_share_name);
```

あとは、読み取り専用のDBとしてアクセスでき、アカウント内にある他のDBと同様にクエリできます。
```sql
USE DATABASE identifier($provider_db_name);
USE SCHEMA identifier($provider_schema_name);
SELECT * FROM identifier($provider_table_name);
```

# 企業内でどう使えそうか
エンタープライズもそうでない会社でも、一つの企業内で複数のアカウントを管理してしまっている場合は良くあると思います。でも、あのデータ（テーブル）を共有したい（してほしい）というシチュエーションは必ずあるので、そいうときにすごく簡単に共有できるので良いですね。

弊社の場合だと、情報システムの会社が独立して存在しており、その会社が管理運用している基幹システムのデータを、すべてこの機能で共有してくれると、使い勝手がめちゃくちゃ向上し、データ活用を促進する一手になると捉えました。今は、いちいちcsvで吐き出してもらって、FTPで取りにいくとか、HULFTやAsteriaを使うとか…。苦労しかない。

また逆のパターン、事業会社からデータを集めたい場合（提出しなければいけない場合）も、この機能を使って共有すれば「ココ見てね」で終わるので、いいなぁ。

そんな楽な世界を夢見てデータ活用を推進していきます。

以下、公式ドキュメントです。

https://docs.snowflake.com/ja/user-guide-data-share.html