[初心者向け] Google BigQueryの基礎を理解してGoogle Cloud Consoleから触ってみた

2020.12.01

当エントリは『クラスメソッド BigQuery Advent Calendar 2020』1日目のエントリです。
本アドベントカレンダーでは、本日(12/01)〜12/25までの間、弊社DA(データアナリィクス)事業本部のメンバーがBigQueryに関連するブログを公開していきます。

まず1本目ということで、BigQuery初心者向けの超入門ブログとしてまとめていきたいと思います。

BigQueryとは

BigQueryはGoogle Cloud Platform(GCP)で提供されているるエンタープライズ向けのデータウェアハウス(DWH)になります。
もともとはGoogle社内で利用していた「Dremel(ドレメル)」という大規模なクエリ実行サービスを社外向けのサービスとして公開されたのがBigQueryのはじまりです。

最大の特徴は、「高速なデータ処理」と言われています。
数TB(テラバイト)、数PB(ペタバイト)規模のデータを数十秒から数分でフルスキャンし、処理結果を高速にユーザーへ返却します。

特徴

高速なデータ処理

BigQueryの最大の特徴とも言える「高速なデータ処理」は、下記2点の仕組みで実現されています。

カラム型データストア

列指向型・カラム型データベース・カラムナストレージなどとも呼ばれます。

一般的なRDBMSでは行単位でデータが保存されていますが、BigQueryでは列単位でデータが保存されています。
このデータ保存方法により、必要なカラムのデータを取得するだけでよく、またデータは圧縮できるため非常に高速な処理が可能となります。
公式論文からの引用ですが、下記がイメージ図となります。

ツリーアーキテクチャ

ツリーアーキテクチャとは、クライアントからクエリを受け取るルートサーバーから、複数のサーバーに対してクエリが指示され並列で処理が行われます。
複数のサーバーに対してツリー構造に拡がってくことで、大規模な並列分散処理を実現しています。
こちらも公式論文からの引用ですが、下記がイメージ図となります。

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

それぞれのテーブルは自動で圧縮、暗号化されます。メンテナンス、バージョンアップのダウンタイムもありません。
インフラの保守・運用はBigQuery側がやってくれるので、本来やりたいこと(データ収集、分析)に集中できます。

SQLでの操作

SQLを書ければ、馴染みのあるSELECT文などでデータを取得することが可能です。
またBigQueryには、「標準SQL」と「レガシーSQL」の2種類のSQLが利用できます。違いなどについては下記ブログをご参照いただければと思います。

安価なコスト

他のDWH(Amazon Redshiftなど)と異なり、BigQueryはクエリを実行する時にサービス(コンテナ)が起動され検索などの操作を行えます。
料金が発生するのはサービス(コンテナ)が起動している間のみ、つまりクエリ操作をしている時のみ発生します。(DWHのサービス起動時間という観点では料金が発生しないようですね)
データ保存については、別途ストレージの料金としてかかりますが、こちらも安価なコストで利用できます。

料金体系

BigQueryにおいて課金対象となるのは主にクエリ・ストレージの2種類です。

クエリの料金

オンデマンドと定額の2つの料金モデルがあります。

  • オンデマンド:実行クエリが処理したバイト数に基づいて算出
  • 定額:予めリソースを購入する。年・月のいずれかの単位で選択が可能

ストレージの料金

ストレージの料金は、「アクティブ」と「長期」の2つのデータ保存期間によって料金が変わります。

  • アクティブ:過去90日以内に更新されたデータ
  • 長期:90日間更新されてないデータ

さらに詳細な料金の情報については、公式ドキュメントの料金表などがわかりやすかったので、そちらをご参照いただければと思います。 またコスト管理方法については、下記ブログもあわせてご参照ください。 BigQueryでは、このクエリを実行するとどれくらいのデータ量が処理され、そのデータ量がいくらなのかというのを事前に見積もりができるんですね〜

BigQueryの操作

BigQueryは主に3つの方法で操作することが可能です。

  • Google Cloud Console
  • bqコマンドラインツール
  • BigQuery REST APIまたはクライアントライブラリ

用語・概念

プロジェクト

プロジェクトとは、GCPプロジェクトとも呼ばれ、Google Cloud Platform上で定義されているプロジェクトを指します。
BigQueryを利用する際は、このプロジェクトの中に後述するデータセット、テーブルなどを作成することで利用することができます。
また課金の単位はこのプロジェクト単位で発生していきます。

データセット

テーブル、ビューへのアクセスを整理して制御するための最上位コンテナとなります。
テーブルまたはビューはデータセットに属する必要があります。

テーブル

個々のレコードが行の形式にまとまったものです。レコードは列(フィールド)で構成されています。
BigQueryは次の3つのテーブルタイプがあります。

  • ネイティブテーブル:BigQuery ストレージに格納されるテーブル
  • 外部テーブル:BigQuery の外部にあるストレージ(Google Cloud Storage や Google ドライブ等)でサポートするテーブル
  • ビュー:SQL クエリによって定義される仮想テーブル

ジョブ

ジョブとは、データの読み込み、データのエクスポート、データのクエリ、データのコピーなど、BigQuery がユーザーに代わって実行するアクション単位です
ジョブの実行には長い時間がかかる場合があるため、ジョブは非同期で実行され、ステータスをポーリングできます。
リソースの一覧表示やメタデータの取得など、短時間のアクションは、ジョブリソースでは管理されません。

触ってみた

上記をざっくりと把握したので、早速、公式のチュートリアルを参考にBigQueryを触ってみました!
※本記事ではプロジェクトは既に作成・選択済みの前提で手順を進めていきます。

Cloud Console を使用したクイックスタート

まずは超入門ということで、一番手取り早くできる下記のチュートリアルを参考に触ってみました。

一般公開データセットをクエリする

既にBigQuery側で用意されている「一般公開データセット」のテーブルデータを参照します。 下記のURLにアクセスします。

https://console.cloud.google.com/bigquery?p=bigquery-public-data&page=project

アクセスすると、クエリエディタ画面が表示されました。 またナビゲーションパネルの[リソース]セクションでbigquery-public-dataも表示されています。

一般公開データセットには、いろんなデータセットがあるようで、覗いたら「wikipedia」という馴染みのある単語のデータセットがあったので、データ取得してみました。
※チュートリアルでは、「usa_names」というデータセットの「usa_1910_2013」というテーブルのデータを取得しています。

まず件数が何件あるのか調べてみようと思い、select count(*) 〜をクエリエディタ上で記述すると、検証ツール上でエラーが出てました。

エラーメッセージからすると、(おそらく件数が多すぎるからか)datehourカラムで期間を絞らないと取得できないようですね。
datehourで2020-11-01からのデータを取得するようにしました。 検証ツール上でも「有効です。」と表示され、「このクエリを実行すると、31.2 GBが処理されます。」とクエリエディタの右下に表示されました。
クエリエディタ上からクエリ実行する場合は、これで事前に処理データ量を把握することができるんですね〜

「実行」をクリックすると、件数が取得できました〜。

実際のデータ取得も問題できなくできました。

select
    datehour,
    wiki,
    title,
    views
from
    `bigquery-public-data.wikipedia.pageviews_2020`
where
    datehour >= '2020-11-29'
group by
    datehour,
    wiki,
    title,
    views

テーブルにデータを読み込む

今回は日本アマチュアゴルフランキングのランキングデータをサンプルデータとして使わせていただきました。

データセットを作成していきます。データセットIDに任意の値、データのロケーションは東京(asia-northeast1)を指定し、「データセットの作成」をクリックしました。

次に「+」ボタンから、テーブルの作成をしていきます。

取り込むデータソースとして、テーブルの作成元に「アップロード」、対象のファイル名、ファイル形式に「CSV」を指定しました。

カラム名、型を指定します。

スキップするヘッダ行を「1」を指定して、「テーブルの作成」をクリックします。

無事指定したテーブル名(ranking)で作成できてました。プレビューでデータも確認できてました。

SQLクエリで欲しいデータも取得できました!

select
    rank,
    pre_rank,
    name,
    age
from
    `ohama-nagamasa.amature_golf.ranking`
where
    rank < 100
order by
    rank

クリーンアップ

最後に作成したデータセットを削除しました。

確認画面でデータセットIDを入力して、「削除」ボタンをクリックします。

データセットを削除することで、属していたテーブル及びテーブルのデータも削除されました。

おわりに

今回はBigQueryの初歩的な内容を書かせていただきました!
まだ触れてないbqコマンドラインツールやBigQuery REST APIでの操作も触っていこうと思います。

2日目は、さがらさんの「BigQuery&Lookerでのクエリデータ量の変化を調べてみた」です!お楽しみに!
以上、DA(データアナリティクス)事業部のナガマサでした〜

参考