BigQuery　調べたことまとめ

# BigQueryについて

https://dev.classmethod.jp/articles/google-bigquery-debut/		

GCで提供されているエンタープライズ向けのデータウェアハウス

## 特徴


### 高速なデータ処理を行える

これを支える2点の仕組みが
・カラム型データストア
　列指向でデータを保存する
　データ取得の際にすべての行を取得するのではなく、対象の列のみを取得できるので早い
・ツリーアーキテクチャ
　クライアントからクエリを受け取ったルートサーバーが複数のサーバーに対してクエリの指示をする
　→並列で処理することができ、且つツリー上に下層に広がっていくので、大規模な並列分散処理ができる


### サーバーレス&フルマネージド

・インフラの保守&運用の必要がない(SaaS)
・それぞれのテーブルは自動で圧縮・暗号化される


### SQLでの操作

なじみのあるSQLのDMLなどでクエリを書くことができる
→標準SQLとレガシーSQLというものがあるらしい
→WITH句やサブクエリなどを実装したのが標準SQLで、その前からあるのがレガシーSQL


### 安価なコスト

クエリの実行時と保有しているデータ量で課金される
また、クエリ実行前にドライランをすることで実行するクエリの見積もりを行うことができる
→明らかにおかしいクエリ(大規模データをフルスキャンしてしまうようなクエリ)を書いてしまい、多額の請求が来てしまうような事態を防げる
　→これに関してはドライラン以外でも対応できるらしい

参考：https://dev.classmethod.jp/articles/bigquery-cost-manage-module/

## 料金体系

金額については以下二つがかかってくる

参考：https://qiita.com/itkr/items/745d54c781badc148bb9

### クエリ

・オンデマンド(実行クエリの処理したバイト数で算出)
・定額(あらかじめリソースを購入する)


### ストレージ

ストレージに保存しているデータは保存期間によって料金が異なる
・アクティブ(90日以内に更新があるデータ)
・長期(90日以内に更新がないデータ)



## BigQueryの操作

三つある

### Google Cloud Console

GCPが提供するブラウザ上で利用する実行基盤


### bqコマンドラインツール

bqコマンドを実行するにはGCPが提供するCloud SDKをインストールしてある必要がある
GCP の Cloud Shellを利用すればデフォルトでインストールしてあるので問題ない
ローカルで実行する際はインストールすること

参考：https://gktechblog.com/bq-using-cli/


### BigQuery REST API またはクライアントライブラリ

BigQueryが用意しているAPIを使用してアプリケーション側からリクエストすることができる

https://qiita.com/itkr/items/12a3df1dc7a6017d0062#:~:text=BigQuery%E3%81%AEAPI%E3%81%AF%20REST%20API%20%E3%81%A8%E3%81%97%E3%81%A6%E7%94%A8%E6%84%8F%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%81%A6%E3%80%81%20Projects%20%E3%83%BB%20Datasets%20%E3%83%BB,%E3%81%A8%E3%81%84%E3%81%86%E3%82%B3%E3%83%AC%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%8C%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82%20REST%20API%20%E3%81%A7%E3%81%99%E3%81%AE%E3%81%A7%20get%20%E3%82%84%20list%20%E3%81%AA%E3%81%A9%E3%81%8A%E3%81%AA%E3%81%98%E3%81%BF%E3%81%AE%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%A7%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%EF%BC%88%E3%82%B3%E3%83%AC%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E7%89%B9%E6%80%A7%E4%B8%8A%E7%94%A8%E6%84%8F%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%82%82%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%EF%BC%89%E3%80%82



## 用語・概念

### プロジェクト

Google Cloud Platform上で定義されているプロジェクトのこと
プロジェクト単位で課金が発生する
プロジェクト内にデータセット、テーブルを作成していく


### データセット

テーブルやビューへのアクセスを整理して制御するコンテナ
データセット内にテーブルやビューは属する


### テーブル

個々のレコードが行の形式にまとまっている
レコードは列単位で構成される
3つのテーブルがある
・ネイティブテーブル(BigQuery内のテーブル)
・外部テーブル(BigQuery外のストレージ)
・ビュー(SQLクエリで定義される仮想テーブル)


### ジョブ

データの読込、エクスポート、クエリ、コピーをBigQuerygがユーザーから代行するアクションの単位
ジョブは非同期実行され、ステータスをポーリングできる

他参照：https://dev.classmethod.jp/referencecat/classmethod-bigquery-advent-calendar-2020/



# BigQuery(DWH)でのテーブル設計について

参考：https://qiita.com/esakik/items/c9ef1516e48c9f666621

DWHでテーブル設計する際には通常のRDBの構造とは異なる手順となるので注意
BigQueryは列指向なので、それを踏まえた設計が必要となる(通常のRDBは行指向が多い)

## パーティション分割テーブル

BigQueryテーブルを時間や日付などの単位でパーティションと呼ばれるセグメントに分割して保存することができる機能
列指向構造の場合は、フルスキャンであれば同列をすべてスキャンすることになる
→これを時間軸などでパーティショニングすることで、必要なセグメントのみを対象に抽出することが可能になる
→これによりスロット消費量、クエリ料金を抑えることができる

パーティションを設定すると、クエリでパーティションを指定することを強制する「パーティションフィルタ」を設定できる
→パーティションの指定し忘れによるフルスキャンを防ぐことができる


## クラスタ化テーブル

指定した1つ以上のフィールドの値に応じてデータを並び替えることで、不要なデータ読み取りの省略とクエリの高速化を行うことができる機能
→最初からOrder By等で並び変えられているような感じ

パーティションテーブルの中では、各セグメントに対してクラスタリングが維持されることになる
→パーティショニングした単位(時間軸とか特定のフィールドとか)でID等を昇順ソートして保持される感じ？


## マテリアライズドビュー

通常のビューの機能(仮想テーブル)以外にも、クエリの結果を定期的にキャッシュすることができる
→高頻度で発生するクエリをキャッシュしておくためのビューを作成することができる
→変換や前処理を含むクエリを特定の高頻度で指定されるリソース(ビュー)が存在する時等

ただし、制限も多い(集計関数の利用が必須、JOINをできない)
キャッシュが必要なJOINのないVIEWやスケジュールドクエリを置き換える

詳しいことは公式や以下に書いてある

参考：https://queuery.com/docs/bigquery-materialized-views/


## UDF(ユーザー定義関数)

一般的なUDFと一緒(スカラー値の指定に使用することで変換処理などを一つのクエリにまとめられるなどの恩恵)
→GitHubコミュニティで多様なUDFが公開されている
→ユースケースに合わせて使用すれば作成する時間を短縮できる

GitHub：https://github.com/GoogleCloudPlatform/bigquery-utils/tree/master/udfs/community
Description by ZOZO：https://techblog.zozo.com/entry/bigquery-udf


## ストアド、BigQueryスクリプト

通常のストアドと同じ利点
(手続き的な内容をひとまとめにできる、データベースへの問い合わせが減る等(これはBigQuery内であればあまり必要でないメリット))



# BigQueryのスロットについて

参考：https://tech.plaid.co.jp/bigquery-slot-resource-optmization/

クエリを実行する際に使用されるCPUとRAMで構成されるコンピューティング能力の単位のこと
クエリのサイズと複雑さに応じて自動的にBigQuery側で計算し、リソースを確保して実行することになる

このスロットという計算資源について、フルマネージドで使うこともできるし
Reservationという一定数のリソースを事前に確保しておくこともできる
Reservationした場合は、企業内で確保したスロットをプロジェクト単位などで細かく制御することも可能になる