インフラ

BigQueryのデータセット設計:ロケーション不可逆・層別分割・権限分離の実装指針

データセットを1つ作るとき、画面で入力するのはIDとロケーションだけで、作業は10秒で終わります。ところがロケーションは作成後に変更できず、後から気づいたときにはコピーか再作成しか手段が残りません。データセットはテーブルとビューを収める入れ物であると同時に、アクセス権を配る単位でもあり、クエリが跨げる範囲を決める境界でもあります。2026年8月17日時点の公式ドキュメントをもとに、保存先の決め方、層と環境の分割設計、IAMと承認済みビューによる権限分離、命名規約と有効期限、そして分けすぎたときに何が壊れるかまでを整理します。

まとめ:データセット設計で先に固定する4点と後から戻せない境界

データセット設計で最初に固定すべきは、ロケーション・分割軸・権限の配り方・命名規約の4点です。このうち後から戻せないのはロケーションだけで、残る3つは運用しながら直せます。保存先の決定に時間を割き、他は走りながら整える順番が実務に合います。

ロケーションは作成時にしか指定できません。変更するにはデータセットをコピーするか、別ロケーションに作り直してデータを入れ直すことになります。しかも1つのクエリが参照するテーブルはすべて同じロケーションに置かれている必要があり、東京と大阪に分けたテーブルを後からJOINすることはできません。

分割軸は、加工段階(raw・staging・mart)を第一軸、環境(本番・検証)を第二軸に置く形が扱いやすい構成です。部署や案件を第一軸にすると、同じデータが複数のデータセットに複製され、権限管理も参照関係も追えなくなります。権限はデータセットレベルのIAMを基本にし、テーブル単位の付与は例外に留めてください。ソースを見せずに結果だけ渡す場面では承認済みビュー、組織の外へ渡す場面ではBigQuery sharingという切り分けです。

データセットの役割:プロジェクトとテーブルの間でアクセスを束ねる単位

データセットを「フォルダのようなもの」と説明した記事は多いのですが、実際の役割はもう少し限定的です。整理のための入れ物であると同時に、権限とロケーションの適用単位でもあり、この二重性を押さえないと後の分割設計で判断がぶれます。

最上位コンテナの収容範囲:テーブル・ビュー・ルーチンとプロジェクト内一意性

公式ドキュメントはデータセットを「特定のプロジェクトに含まれる、テーブルとビューを整理しアクセスを制御するための最上位コンテナ」と定義しています。BigQueryの階層は組織、プロジェクト、データセット、テーブルの4段で、データセットの入れ子はできません。

データセットに収まるのはテーブル、ビュー、マテリアライズドビュー、ルーチン(ユーザー定義関数やストアドプロシージャ)、モデルです。データセット名(データセットID)はプロジェクト内で一意である必要があり、別プロジェクトなら同じIDを使えます。この性質は環境分離の設計で効いてきます。製品全体の仕組みとサーバーレスDWHとしての位置づけはBigQueryとはという記事でのアーキテクチャ解説で扱いました。

ロケーション決定の不可逆性:東京・大阪・マルチリージョンの選択と移行コスト

データセット作成で唯一やり直しがきかないのがロケーションです。ここだけは作る前に決め切る必要があります。判断材料は法規制、レイテンシ、料金、既存データの置き場所の4つです。

作成時だけ指定できる保存先:変更不可の仕様とコピーによる回避手順

公式ドキュメントは「ロケーションは作成時にのみ設定でき、データセット作成後にロケーションを変更することはできない」と明記しています。変えたい場合の手段は2つで、データセットコピーで別ロケーションへ複製するか、新しいロケーションに作り直してデータを入れ直すかです。どちらもテーブル参照を書いている既存のクエリ、スケジュールクエリ、BIツールの接続設定を追随させる作業が付いてきます。

ロケーションを指定せずにジョブを実行した場合、既定ではUSマルチリージョンで動きます。検証中に何気なく作ったデータセットが米国に置かれ、本番設計で東京に決めた段階で作り直しになる。これが最も多い手戻りです。検証用であっても、最初の1つを作る前にロケーションを決めておいてください。

同一ロケーション制約:クエリが参照する全テーブルに及ぶ整合要件

公式ドキュメントは「クエリで参照されるすべてのテーブルは、同じロケーションのデータセットに保存されている必要がある」と述べています。この制約はJOINだけでなく、UNIONやサブクエリからの参照にも及びます。

注意したいのは、単一リージョンとマルチリージョンが一致扱いにならない点です。ジョブのロケーションがUSマルチリージョンで、参照先がus-central1のデータセットである場合、両者は同じ地理的範囲にあってもロケーションとしては一致しません。

マルチリージョンと単一リージョンの選択基準:法規制・レイテンシ・料金差

選択の優先順位は、法規制、次に参照元との近さ、最後に料金の順です。個人情報や取引データを国内に留める要件があるなら、東京(asia-northeast1)か大阪(asia-northeast2)の単一リージョンで確定します。料金差を理由にUSマルチリージョンを選ぶ余地はありません。

要件がない場合は、データの供給元とBIツールの所在で決めます。Cloud Storageのバケットや外部システムが東京にあるなら東京、分析基盤が米国側のサービスと密に連携するならUSマルチリージョンという判断です。ストレージ単価と分析単価はロケーションごとに異なり、東京は米国マルチリージョンより高い水準です。金額の内訳と課金の考え方はBigQueryの料金を整理した記事のストレージ課金の節で扱っています。

層と環境で分けるデータセット分割設計:命名規約と既定有効期限までの実装

ロケーションが決まったら、次はいくつのデータセットに分けるかです。ここで多いのが「部署ごとに1つ」という切り方ですが、分析基盤としては加工段階で切るほうが権限もコストも整理しやすくなります。

raw・staging・martの3層分割:加工段階で権限と削除ポリシーを切る設計

層別分割は、取り込んだままの生データ、加工途中の中間データ、利用者に見せる集計済みデータの3つに分ける方法です。各層のテーブルをDDLでどう定義し直すかは、BigQueryのCREATE TABLE:パーティション指定とMERGEの実装指針でテーブル物理設計の側から扱っています。生データは書き込み系のサービスアカウントだけが触ればよく、分析者に見せる必要がありません。中間データはパイプラインの内部事情で、外に開くと仕様変更のたびに問い合わせが発生します。

  • raw層:取り込み専用。パイプラインのサービスアカウントに編集権限、分析者には付与しない
  • staging層:加工の中間結果。データエンジニアのみ。テーブル有効期限で自動削除する対象
  • mart層:利用者向け。分析者とBIツールに閲覧権限を配る唯一の層

削除ポリシーも層ごとに変わります。staging層は再生成できるため既定テーブル有効期限を設定して放置し、mart層は消えると業務が止まるので期限を設定しません。層の考え方そのものはBigQuery固有ではなく、データレイクからDWHへの流れと共通しています。

環境分離の2案比較:プロジェクト分離とデータセット接尾辞の判断基準

本番と検証をどう分けるかには2つの案があります。プロジェクトごと分ける案と、同じプロジェクト内でデータセット名の接尾辞で分ける案です。

観点 プロジェクト分離 データセット接尾辞
権限の隔離 プロジェクト単位で完全に分離できる データセットごとに個別付与が必要
課金の分離 請求先を分けられる ラベルで按分するしかない
クエリの移植 プロジェクトIDの書き換えが必要 データセット名の書き換えのみ
誤操作リスク 低い(別プロジェクトを明示的に選ぶ) 高い(一覧に本番と検証が並ぶ)
向く規模 本番データに規制がある・チームが分かれる 少人数で同一チームが両方を触る

規制対象のデータを扱うならプロジェクト分離を選びます。本番と検証が同じ画面に並ぶ状態は、削除事故が起きたときに言い訳が立ちません。3〜4人のチームが両方を行き来する規模なら、接尾辞方式のほうが切り替えコストは低く済みます。

命名規約の作り方:使える文字と1,024文字上限・大文字小文字の落とし穴

データセットIDに使えるのは英字(大文字と小文字)、数字、アンダースコアだけです。ハイフンやスペース、アンパサンドは受け付けません。長さは最大1,024文字まで許容されますが、実務で上限に近づく理由はありません。既定では大文字小文字が区別され、Sales_Martsales_martは別のデータセットとして共存します。

事故を避けるなら、規約は小文字とアンダースコアだけに固定するのが安全です。並び順も同時に決めてください。層、ドメイン、環境の順に並べてmart_sales_prodとすると、コンソールの一覧が層ごとにまとまり、権限の棚卸しが上から順に進みます。

既定テーブル有効期限とメタデータ更新上限:運用で効く2つの設定値

データセットには既定テーブル有効期限を設定できます。設定すると、そのデータセット内に新しく作られたテーブルは指定期間の経過後に自動削除され、最小値は1時間です。staging層やアドホック検証用のデータセットに入れておくと、消し忘れたテーブルがストレージ課金として積み上がる状態を防げます。既存テーブルには遡って適用されない点に注意してください。

もう1つの設定値がメタデータ更新の上限です。データセットのメタデータ更新オペレーションは1データセットあたり10秒間に5回までに制限されており、コンソール、bqコマンド、datasets.insert・datasets.patch・datasets.updateのAPI呼び出しがこの枠を共有します。TerraformからアクセスACLを一括更新するとこの上限に触れるため、権限付与を自動化するなら更新を1回のパッチにまとめる実装が要ります。

IAMと承認済みビューによる権限分離:dataViewerとjobUserの二重要件

データセットを分けても権限の配り方を間違えると設計は機能しません。最初につまずくのは、閲覧権限を与えたのにクエリが実行できない現象で、原因は仕様であって設定ミスではありません。

データセットレベルで付与できるロール:閲覧・編集・所有の権限差

データセットに付けられる主なロールは4つで、守備範囲は次のように分かれます。

ロール(roles/ 略) メタデータ参照 データ読み取り テーブル作成・更新 権限の変更
bigquery.metadataViewer 不可 不可 不可
bigquery.dataViewer 不可 不可
bigquery.dataEditor 不可
bigquery.dataOwner

metadataViewerとdataViewerの差は「中身を読めるか」の一点です。テーブルの存在とスキーマだけ知らせて実データは伏せたい相手、たとえばカタログを横断検索させたい利用者にはmetadataViewerが合います。mart層の分析者にはdataViewer、パイプラインのサービスアカウントにはraw層とstaging層でdataEditorが基本形です。

クエリ実行に必要な二重権限:jobUserがプロジェクト以上でしか付かない理由

ここが最初の関門です。roles/bigquery.jobUserは「Resource Manager のリソース(プロジェクト、フォルダ、組織)に対してのみ付与できる」とドキュメントに明記されています。データセットには付けられません。クエリはジョブとして実行され、ジョブはプロジェクトに属するからです。

つまり分析者がクエリを1本実行するには、データセットに対するdataViewerと、プロジェクトに対するjobUserの両方が要ります。片方だけでは、テーブル一覧は見えてもクエリが通りません。設計上は、jobUserを「クエリを実行してよい人の集合」としてプロジェクトレベルのGoogleグループへ一度だけ付与し、どのデータを見せるかはデータセット側のdataViewerで制御してください。サービスアカウントに同じ組み合わせを付ける実装や認証の詳細はBigQuery APIの選び方をまとめた記事の権限設計の節で扱っています。

承認済みビューと承認済みデータセット:ソースを開かずに結果だけ渡す構成

特定の行や列だけを見せたいが、元テーブルには触らせたくない。この要求に応えるのが承認済みビューです。ビューを承認すると、参照する側にソースデータセットの権限がなくてもビュー経由でクエリできます。公式ドキュメントの表現では「ソースデータセットには直接アクセスできない」状態です。

構成の決まりは3つです。ビューはソースとは別のデータセットに置くこと、ソースとビューのデータセットが同じロケーションにあること、利用者にはビュー側のdataViewerとプロジェクトのjobUserを付けること。ビューが増えたら1本ずつ承認する代わりに、データセット全体を承認する承認済みデータセットへ切り替えます。運用上の落とし穴として、承認済みビューを削除すると同じ名前で24時間は再作成できません。

BigQuery sharingとリンクされたデータセット:組織外共有の構造と選択条件

共有相手が自社の組織外に出た時点で、IAMと承認済みビューの延長では扱いきれなくなります。相手のプリンシパルを自社プロジェクトのIAMに追加し続ける運用は、相手が増えるほど棚卸しが困難です。ここで使うのがBigQuery sharing(旧Analytics Hub)です。

交換・リスティング・リンクされたデータセットの関係:コピーなし共有の仕組み

BigQuery sharingは3つの要素で構成されます。データ交換(exchange)は共有の枠組みとなるコンテナ、リスティング(listing)はその中に掲載される共有リソースへの参照、リンクされたデータセット(linked dataset)は購読者側に作られる読み取り専用のデータセットです。

リンクされたデータセットは実体のコピーではなく、共有元データセットへのポインタとして機能します。ストレージとコンピュートが分離されたアーキテクチャがこれを可能にしており、公開側は購読者が増えてもデータを複製せずに済みます。課金は公開側がストレージ料金、購読側がクエリ料金を負担する形です。

承認済みビューとsharingの選び分け:共有相手が組織外かどうかの分岐

判断は共有相手の所在で切ってください。自社組織内で部署をまたぐだけなら承認済みビューで足ります。IAMで閉じる構成のほうが構造は単純で、監査もIAMポリシーの確認だけで済みます。

組織外に継続的に配る場合はsharingを選びます。取引先へのデータ提供、グループ会社間のデータ交換、社外向けのデータ製品といった用途です。分岐点は相手が増減するかどうかで、入れ替わりのある共有をIAMで管理し続けると、退会した相手の権限が残る事故が起きます。単発かつ相手が固定なら、承認済みビューのほうが速く終わります。

データセットを分けすぎる設計の損益分岐:1つで足りる条件と分割が必須になる境界

ここまで分割の設計を扱いましたが、分けること自体に価値はありません。データセットを増やすほど権限付与の対象が増え、クエリのFROM句が長くなり、棚卸しの手間が積み上がります。分けるべきでない場面を先に決めておくほうが、後の運用は軽くなります。

1データセットで足りる条件:単一チーム・権限差なし・同一ロケーション

次の3つがすべて成り立つなら、データセットは1つで足ります。第一に、データを触る人が単一チームに収まっていること。第二に、そのチーム内で見せてよいデータと見せられないデータの区別がないこと。第三に、保存先ロケーションを分ける規制要件がないことです。

この条件下で層別に3つ作っても、得られるのは名前空間の整理だけで、権限付与は3倍になります。数十テーブル規模の立ち上げ段階なら、テーブル名の接頭辞で層を表現し、データセットは1つで始めるほうが速く回ります。ロケーションと違い、分割は必要になった時点で後から実施できる変更です。基盤の立ち上げ方針を検討している段階であれば、データ分析基盤構築・MLOps構築支援で設計から運用体制までの相談を受け付けています。

分割を見送るべき場面:部署単位の細分化がJOINと権限管理を壊す条件

逆に、明確に見送るべき分割があります。部署単位・案件単位でデータセットを切る設計です。この形は組織図に沿っていて説明しやすいのですが、実務では3つの理由で破綻します。

1つ目は重複です。営業部と経営企画部が同じ受注データを見るなら、部署ごとに持った時点で同じテーブルが2箇所に生まれ、片方だけ更新される状態が生じます。2つ目は参照の分断で、部署をまたぐ分析のたびにFROM句へ複数のデータセットを並べることになり、どちらが正なのか判断できません。3つ目は権限の形骸化で、横断の分析要求が来るたびに例外的な付与が積み上がり、最終的に全員が全データセットのdataViewerを持つ状態に収束します。

組織の切り口で見せ分けたいなら、データセットを分けるのではなく、mart層の中で承認済みビューを部署別に用意してください。実体は1つのまま、見える範囲だけを変えられます。ただし承認済みリソースはデータセットのアクセス制御リストで合計2,500件までが上限で、承認済みビュー・データセット・関数の合算で数えます。部署×テーブルの掛け算で機械的に量産すると、数千の規模でこの上限に接近する点に注意してください。段階を追った導入の進め方はBigQuery導入の手順と体制を整理した記事にまとめています。

よくある質問:データセットの作成・変更・権限でつまずきやすい論点

設計と運用で繰り返し出てくる質問を5つ挙げ、公式ドキュメントの記載に沿って答えます。

データセットのロケーションを後から東京に変更できますか?

変更はできません。公式ドキュメントは「データセット作成後にロケーションを変更することはできない」と明記しており、手段はデータセットコピーで東京リージョンへ複製するか、東京に新しいデータセットを作ってデータを入れ直すかの2つです。どちらも既存のクエリやBIツールの接続先を向け直す作業が伴います。未指定のまま作るとUSマルチリージョンになるため、最初の1つを作る前に決めておいてください。

データセットIDにハイフンを使えないのはなぜですか?

データセットIDに使える文字が英字、数字、アンダースコアに限定されているためです。ハイフンやスペース、アンパサンドは受け付けません。プロジェクトIDにはハイフンが使えるため、my-project.sales_martのようにプロジェクト側だけハイフンを含む形になります。この非対称が混乱を招くため、命名規約は小文字とアンダースコアのみに統一してください。IDの長さは最大1,024文字までです。

dataViewerを付けたのにクエリが実行できないのはなぜですか?

クエリの実行にはジョブの作成権限が別途必要だからです。roles/bigquery.jobUserはプロジェクト、フォルダ、組織に対してのみ付与でき、データセットには付けられません。dataViewerだけを持つ利用者は、テーブル一覧やスキーマは参照できてもクエリを投げた時点で失敗します。プロジェクトレベルでjobUserを付与し、見せたいデータセットにdataViewerを付ける二段構えが要ります。

1つのクエリで別ロケーションのデータセットを結合できますか?

基本的にはできません。公式ドキュメントは「クエリで参照されるすべてのテーブルは同じロケーションのデータセットに保存されている必要がある」と述べています。ジョブがUSマルチリージョンで参照先がus-central1なら、地理的に重なっていても一致扱いにはなりません。跨いで分析するなら、データセットコピーで片方に寄せる判断になります。

staging層のテーブルを自動で消す設定はありますか?

データセットの既定テーブル有効期限を使います。設定しておくと、そのデータセット内に新しく作成されたテーブルが指定期間の経過後に自動削除され、最小値は1時間です。中間データや検証用テーブルを置くデータセットに設定すると、消し忘れによるストレージ課金の蓄積を抑えられます。既存テーブルには遡って適用されないため、導入時点のテーブルには個別に設定してください。mart層のように消えると業務が止まるデータセットには設定しません。

関連記事

資料請求

RELATED POSTS 関連記事