
始める前に
- ラボでは、Google Cloud プロジェクトとリソースを一定の時間利用します
- ラボには時間制限があり、一時停止機能はありません。ラボを終了した場合は、最初からやり直す必要があります。
- 画面左上の [ラボを開始] をクリックして開始します
BigQuery は、Google が低価格で提供する NoOps、フルマネージドの分析データベースです。BigQuery では、インフラストラクチャを所有して管理したりデータベース管理者を置いたりすることなく、テラバイト単位の大規模なデータでクエリを実行できます。また、SQL が採用されており、従量課金制というメリットがあります。このような特徴を活かし、お客様は有用な情報を得るためのデータ分析に専念できます。
このラボでは、BigQuery での半構造化データの操作(JSON や配列データ型の取り込み)について詳しく学習します。スキーマを非正規化し、ネストされた繰り返しフィールドを持つ単一のテーブルにすることで、パフォーマンスが向上する場合があります。ただし、配列データを操作する SQL 構文は複雑になることがあります。ここでは、さまざまな半構造化データセットに対する読み込み、クエリ実行、トラブルシューティング、ネスト解除を実際に行います。
このラボでは、次の方法について学びます。
各ラボでは、新しい Google Cloud プロジェクトとリソースセットを一定時間無料で利用できます。
Qwiklabs にシークレット ウィンドウでログインします。
ラボのアクセス時間(例: 1:15:00
)に注意し、時間内に完了できるようにしてください。
一時停止機能はありません。必要な場合はやり直せますが、最初からになります。
準備ができたら、[ラボを開始] をクリックします。
ラボの認証情報(ユーザー名とパスワード)をメモしておきます。この情報は、Google Cloud Console にログインする際に使用します。
[Google Console を開く] をクリックします。
[別のアカウントを使用] をクリックし、このラボの認証情報をコピーしてプロンプトに貼り付けます。
他の認証情報を使用すると、エラーが発生したり、料金の請求が発生したりします。
利用規約に同意し、再設定用のリソースページをスキップします。
[Cloud Console の BigQuery へようこそ] メッセージ ボックスが開きます。このメッセージ ボックスにはクイックスタート ガイドへのリンクと、UI の更新情報が表示されます。
新しいデータセットに「fruit_store
」という名前を付けます。その他のオプションはデフォルト値([データのロケーション]、[デフォルトのテーブルの有効期限])のままにし、
[データセットを作成] をクリックします。
通常、SQL では、以下の果物リストのように各行に値が 1 つ含まれます。
行 | 果物 |
---|---|
1 | raspberry |
2 | blackberry |
3 | strawberry |
4 | cherry |
果物リストに店舗の担当者名が必要な場合はどうすればよいでしょうか。次のようになります。
行 | 果物 | 担当者 |
---|---|---|
1 | raspberry | sally |
2 | blackberry | sally |
3 | strawberry | sally |
4 | cherry | sally |
5 | orange | frederick |
6 | apple | frederick |
従来のリレーショナル データベースの SQL では、同じ名前が複数回出現する場合、上記のテーブルを果物と担当者の 2 つの別個のテーブルに分割することを考えます。
BigQuery では、配列データ型を使用して以下のような形を実現することで、より簡単に対応できます。
行 | 果物(配列) | 担当者 |
---|---|---|
1 | raspberry | sally |
blackberry | ||
strawberry | ||
cherry | ||
2 | orange | frederick |
apple |
従来のテーブルとこのテーブルの違いを確認しましょう。
以下のように記述すると、果物の配列について理解しやすくなります。
行 | 果物(配列) | 担当者 |
---|---|---|
1 | [raspberry, blackberry, strawberry, cherry] | sally |
2 | [orange, apple] | frederick |
これら両方のテーブルは同じ内容を表します。主な学習のポイントは 2 つあります。
[実行] をクリックします。
次のクエリを実行します。
次のようなエラーが表示されます。
Error: Array elements of types {INT64, STRING} do not have a common supertype at [3:1]
配列内では同じデータ型を使用する必要があります(すべて文字列、すべて数値など)。ここで、配列の配列は作成できるのか疑問に思われるかもしれませんが、作成は可能です。この点については後で説明します。
[実行] をクリックします。
結果が表示されたら [JSON] タブをクリックして、ネストされた結果の構造を確認します。
BigQuery に JSON ファイルを取り込む必要がある場合はどうすればよいでしょうか。実際に試してみましょう。
fruit_store
データセットに新しいテーブルを作成します。
テーブルを作成するには、fruit_store データセットの横にある「アクションを表示」アイコンをクリックし、[開く] を選択します。
次に右側のパネルの [テーブルを作成] をクリックします。
cloud-training/data-insights-course/labs/optimizing-for-performance/shopping_cart.json
新しいテーブルの名前を「fruit_details
」にします。
[スキーマ] で、[自動検出] チェックボックスをクリックします。
[テーブルを作成] をクリックします。
fruit_details
テーブルをクリックします。
[スキーマ] で fruit_array が「REPEATED
」に設定されているため、このフィールドが配列であることがわかります。
先ほど確認したように、配列には同じデータ型のみを格納できますが、複数のフィールド名とデータ型が存在する場合は STRUCT(構造体)のデータ型を使用できます。
次のデータセットは、トラックを走るランナーのラップタイムです。各ラップは「スプリット」と呼ばれます。
行 | runner.name | runner.split |
---|---|---|
1 | Rudisha | 23.4 |
フィールドのエイリアスについて、どのようなことがわかりますか。構造体内でフィールドがネストされているため(name と split が runner のサブセット)、ドットを使用して表されています。
1 つのレコード内にランナーのスプリットが複数ある場合はどうなるでしょうか。単一のレコードに複数のスプリット タイムを含めるにはどうすればよいでしょうか。ヒント: スプリットはすべて同じデータ型(数値)です。
解答: 配列を使用します。
行 | runner.name | runner.split |
---|---|---|
1 | Rudisha | 23.4 26.3 26.4 26.1 |
まとめると次のようになります。
「racing」という名前の新しいデータセットを作成します。
「race_results」という名前の新しいテーブルを作成します。
以下の Google Cloud Storage の JSON ファイルを取り込みます。
cloud-training/data-insights-course/labs/optimizing-for-performance/race_results.json
cloud-training/data-insights-course/labs/optimizing-for-performance/race_results.json
race_results
に設定します。[テーブルを作成] をクリックします。
読み込みジョブが完了したら、新しく作成されたテーブルをプレビューします。
構造体のフィールドはどれであり、それを知る手掛かりは何でしょうか。
解答: participants フィールドは RECORD 型なので構造体です。
配列のフィールドはどれでしょうか。
解答: participants.splits
フィールドは、親である participants
構造体内の FLOAT の配列です。モードが REPEATED であるため、配列であることがわかります。この配列の値は、単一のフィールドに複数の値が含まれるため「ネストされた値」と呼ばれます。
各ランナーの名前とレースの種類を一覧表示するにはどうすればよいでしょうか。
Error: Cannot access field name on a value with type ARRAY<STRUCT<name STRING, splits ARRAY<FLOAT64>>>> at [2:27]
集計関数を使う際に GROUP BY を忘れた状態に似ています。ここでは、粒度の異なる 2 つの項目があります。レースが 1 行、参加者名が 3 行です。これをどのように変更すればよいでしょうか。
行 | race | participants.name |
---|---|---|
1 | 800M | Rudisha |
2 | ??? | Makhloufi |
3 | ??? | Murphy |
これを次のようにします。
行 | race | participants.name |
---|---|---|
1 | 800M | Rudisha |
2 | 800M | Makhloufi |
3 | 800M | Murphy |
従来のリレーショナル SQL では、レースのテーブルと参加者のテーブルがある場合、両方のテーブルから情報を取得するにはテーブルを結合する必要があります。ここでは、参加者の STRUCT(概念的にはテーブルに似ています)は、すでにレースのテーブルに含まれていますが、STRUCT ではない「race」のフィールドとまだ適切に関連付けられていません。
最初のテーブルで 800M レースを各ランナーと関連付けるために使用する SQL コマンドは何ですか。
解答: CROSS JOIN
では、先に進みましょう。
Error: Table name "participants" missing dataset while no default dataset is set in the request
.
参加者の STRUCT はテーブルに似ていますが、厳密に言えば racing.race_results
テーブル内のフィールドの 1 つです。
結果はどうなりましたか。各レースのランナーがすべて一覧表示されました。
行 | race | name |
---|---|---|
1 | 800M | Rudisha |
2 | 800M | Makhloufi |
3 | 800M | Murphy |
4 | 800M | Bosse |
5 | 800M | Rotich |
6 | 800M | Lewandowski |
7 | 800M | Kipketer |
8 | 800M | Berian |
以下の方法で最後のクエリを簡素化できます。
レースの種類が複数ある場合(800M、100M、200M)、クロス結合では、デカルト積のように各ランナーの名前がすべてのレースと関連付けられることはないのでしょうか。
解答: そのようにはなりません。これは相関クロス結合であり、個々の行に関連付けられた要素のみが展開されます。詳しくは、配列と構造体の操作のリファレンス ドキュメントをご参照ください。
STRUCT(構造体)のまとめ:
STRUCT("Rudisha" as name, [23.4, 26.3, 26.4, 26.1] as splits) AS runner
」を思い出してください。先ほど作成した racing.race_results
テーブルを使用して以下の質問に解答してください。
タスク: 参加したランナーの合計数を取得するクエリを作成してください。
まず、部分的に作成済みの次のクエリを使用します。
ヒント: FROM の後に追加のデータソースとして、構造体名でクロス結合する必要があります。
解答例:
行 | racer_count |
---|---|
1 | 8 |
解答: レースに参加したランナーは 8 人です。
STRUCT の操作方法を確認したので、この知識を利用して、ARRAY を展開して従来の複数行による配列にします。
UNNEST 演算子は ARRAY を受け取り、ARRAY 内の各要素を 1 行にしてテーブルを返します。
これにより、以下のような通常の SQL オペレーションを実行できます。
配列は、要素の順序付きリストであり、要素はすべて同じデータ型である点に注意してください。
8 人のランナーの名前で構成される文字列配列があります。
BigQuery で配列を作成するには、カンマで値を区切り、角かっこ [ ] で囲みます。
解答: 8 個の配列要素がある単一の行が出力されます。
行 | normal_array |
---|---|
1 | Rudisha |
Makhloufi | |
Murphy | |
Bosse | |
Rotich | |
Lewandowski | |
Kipketer | |
Berian |
ヒント: 配列形式ではないフィールドがすでに存在する場合、ARRAY_AGG() を使用して、それらの値を配列にすることができます。
名前が「M」の文字で始まるランナーを探すには、上記の配列を個々の行に展開して WHERE
句を使用できるようにする必要があります。
以下に示すように、配列を展開するには、配列(または配列の名前)を UNNEST()
で囲みます。
次のように出力されます。
行 | unnested_array_of_names |
---|---|
1 | Rudisha |
2 | Makhloufi |
3 | Murphy |
4 | Bosse |
5 | Rotich |
6 | Lewandowski |
7 | Kipketer |
8 | Berian |
これで配列のネストが解除されました。これは、配列のフラット化とも呼ばれます。
行 | unnested_array_of_names |
---|---|
1 | Makhloufi |
2 | Murphy |
名前が「R」で始まるランナーの合計レース時間を一覧表示するクエリを作成します。合計時間が短いランナーが先に表示されるように並べ替えます。UNNEST()
演算子を使って、部分的に作成済みの次のクエリで開始します。
ヒント:
解答例:
行 | name | total_race_time |
---|---|---|
1 | Rudisha | 102.19999999999999 |
2 | Rotich | 103.6 |
800M のレースで最も速いラップタイムは、23.2 秒でした。ただし、それがどのランナーの記録であるかは確認できていません。その結果を返すクエリを作成します。
解答例:
行 | name | split_time |
---|---|---|
1 | Kipketer | 23.2 |
JSON データセットを取り込み、配列と構造体を作成し、半構造化データをネスト解除してインサイトを得ることができました。
ラボが完了したら、[ラボを終了] をクリックします。ラボで使用したリソースが Google Cloud Skills Boost から削除され、アカウントの情報も消去されます。
ラボの評価を求めるダイアログが表示されたら、星の数を選択してコメントを入力し、[送信] をクリックします。
星の数は、それぞれ次の評価を表します。
フィードバックを送信しない場合は、ダイアログ ボックスを閉じてください。
フィードバックやご提案の送信、修正が必要な箇所をご報告いただく際は、[サポート] タブをご利用ください。
Copyright 2020 Google LLC All rights reserved. Google および Google のロゴは Google LLC の商標です。その他すべての企業名および商品名はそれぞれ各社の商標または登録商標です。
このコンテンツは現在ご利用いただけません
利用可能になりましたら、メールでお知らせいたします
ありがとうございます。
利用可能になりましたら、メールでご連絡いたします
1 回に 1 つのラボ
既存のラボをすべて終了して、このラボを開始することを確認してください