BigQueryもCloud SQLも「SQLでクエリできるデータベース」に見えます。実際、どちらもテーブルを持ち、SELECT文で問い合わせます。
しかし両者は同じ土俵のサービスではありません。Cloud SQLはアプリケーションが1件単位で読み書きする業務用DB(OLTP)、BigQueryは蓄積データを大量にスキャンして集計する分析用DB(OLAP)です。分析用DBはDWH(データウェアハウス。分析のために大量のデータを蓄えておく基盤)とも呼ばれます。両者は内部の仕組みも得意なクエリも課金の考え方も別物です。
『GCPのストレージ・データベースはオブジェクトストレージ・アプリケーションDB・DWHの3分類で選ぶ』では、GCPの保存系サービスを3つに分類しました。本記事はその中の分析基盤にあたるBigQueryを、業務用DBの代表であるCloud SQLとの対比で深掘りします。
この記事では、この2つの違いを仕組みから整理し、「どちらを選ぶか」ではなく「どう併用するか」まで扱います。
OLTP / OLAPという分類自体の構造的な違い(なぜ1つのDBで両方をこなせないのか)は『応答速度×スケール方式によるデータベース分類: RDBがスケールアウトしない理由とNoSQLの3つの妥協』で扱っています。本記事はGCPでの使い分けに絞ります。
一覧比較
| 観点 | Cloud SQL | BigQuery |
|---|---|---|
| 位置付け | 業務用DB(OLTP) | 分析用DB(OLAP / DWH) |
| 典型クエリ | 「この注文を1件取得・更新する」 | 「全注文を月別・商品別に集計する」 |
| 1クエリが触る行数 | 少数(インデックスで絞る) | 大量(テーブルを広くスキャンする) |
| データの持ち方 | 行指向 | カラム(列)指向 |
| インフラ | インスタンスを立てる(スペックを選ぶ) | サーバーレス(インスタンス管理なし) |
| 更新 | 頻繁な単行の更新・削除が得意 | 追記が中心。単行の頻繁な更新は不得意 |
| 課金の考え方 | インスタンスの稼働時間とスペック | ストレージ+クエリのスキャン量(または確保した計算枠) |
| 接続 | アプリからコネクションを張る | APIやクライアントからクエリを投げる |
行指向とカラム指向という仕組みの違い
両者の得意分野の違いは、データの持ち方から説明できます。
データベースのテーブルは行と列を持つ2次元の表ですが、ディスク上には1次元に並べて保存するしかありません。このとき1行分のデータをまとめて並べるのが行指向、同じ列の値をまとめて並べるのがカラム(列)指向です。
たとえば注文テーブルに3件のデータがあるとします。
テーブル:
id | user | amount
1 | 田中 | 1200
2 | 佐藤 | 800
3 | 鈴木 | 3000
行指向の並び(Cloud SQL):
[1, 田中, 1200] [2, 佐藤, 800] [3, 鈴木, 3000]
カラム指向の並び(BigQuery):
[1, 2, 3] [田中, 佐藤, 鈴木] [1200, 800, 3000]
- 行指向では、1行分のデータが物理的に隣り合って保存されます
- 「id=2の注文を取得して更新する」なら、その1か所を読むだけで行全体が手に入ります
- インデックスで対象行にたどり着き、1行を丸ごと読み書きする処理が高速です
- カラム指向では、同じ列の値が物理的に隣り合って保存されます
- 「全注文のamountを合計する」なら、amountの並びだけを読めばよく、userなど関係ない列は読まずに済みます
- 少数の列を大量の行にわたってスキャンする集計が高速です。同じ型の値が並ぶため圧縮も効きやすくなります
- 逆に「1行を丸ごと取る」には各列の並びから1つずつ拾い集める必要があり、行指向より不利です
さらにBigQueryはストレージと計算が分離したサーバーレスの構成で、クエリのたびに分散処理の計算リソースが割り当てられます。インスタンスのスペックを気にする必要がない一方、1件だけ取るクエリでも分散処理の起動を伴うため、ミリ秒単位の応答を求めるアプリのバックエンドには向きません。
それぞれが向く処理
- Cloud SQLが向く処理
- アプリケーションのCRUD(注文の作成、ユーザー情報の更新など)
- トランザクションが必要な処理
- 低レイテンシで少数行を返す処理
- BigQueryが向く処理
- 蓄積した大量データの集計・分析
- ダッシュボードやレポートの元データ作成
- ログ・行動データの探索的なクエリ
- データレイク上のデータやGoogleアナリティクスなど、他ソースとの横断分析
アンチパターン
方向を間違えた使い方は、どちら向きでも破綻します。
- BigQueryをアプリのバックエンドDBにする
- 1件単位の読み書きはレイテンシもコストも合いません。スキャン量課金のため、アプリから高頻度にクエリを投げる構成は費用面でも危険です
- Cloud SQLで全件集計の分析クエリを回す
- 業務トラフィックと同じインスタンスで重い集計を実行すると、本番のCRUDが巻き添えでスローダウンします。分析用途が育ってきたら、BigQueryへ切り出すタイミングです
使い分けではなく併用する
実際の設計では「どちらか」ではなく、業務データはCloud SQL、分析はBigQueryと役割を分けたうえで、Cloud SQLのデータをBigQueryへ流し込む構成にします。
flowchart LR app["アプリケーション"] sql["Cloud SQL<br/>業務データ(OLTP)"] bq["BigQuery<br/>分析(OLAP)"] dash["ダッシュボード / レポート"] app -->|"CRUD"| sql sql -->|"バッチ / CDC / 連携クエリ"| bq bq --> dash
連携の代表的な手段は以下です。
- バッチエクスポート
- 日次などでCloud SQLからエクスポートしてBigQueryへロードします。もっとも素朴で、鮮度が日次でよいなら十分です
- 連携クエリ(federated query)
- BigQueryからCloud SQLへ直接クエリを投げる機能です。データをコピーせずに参照できますが、Cloud SQL側に負荷がかかる点は変わりません
- Datastream(CDC)
- 変更データキャプチャでCloud SQLの更新を継続的にBigQueryへ複製します。鮮度が求められる分析に使います
どの手段でも、目的は同じです。業務DBに分析の負荷を持ち込まず、分析基盤に業務の読み書きを持ち込まないことです。
要件キーワードから引く使い分けの早見表
要件のキーワードで整理すると以下です。
| 要件キーワード | 選ぶもの |
|---|---|
| トランザクション、1件単位の読み書き、アプリのバックエンド | Cloud SQL |
| 集計、分析、レポート、ダッシュボード、DWH | BigQuery |
| ペタバイト級のログを分析、アドホックなクエリ | BigQuery |
| 業務データを分析したい | Cloud SQL+BigQueryの併用(連携で流し込む) |
| ストリーミングデータの分析 | BigQuery(Pub/Sub・Dataflowと組み合わせ) |
ストリーミングでBigQueryへデータを流し込む構成は『GCP Pub/Subと周辺サービスの役割分担』で扱っています。
まとめ
BigQueryとCloud SQLは「SQLが使えるDB」という見た目が似ているだけで、業務用DBと分析用DBという別物です。
- 1件単位の読み書きとトランザクションはCloud SQL
- 大量データのスキャンと集計はBigQuery
- 実務では選択ではなく併用が基本形で、業務データを連携手段(バッチ / 連携クエリ / CDC)でBigQueryへ流し込む
「SQLが使えるからBigQueryでアプリを作る」「Cloud SQLがあるから分析もそこでやる」のどちらも、仕組みに逆らう使い方です。