- ジョブ(query / load / extract / copy)という実行単位とライフサイクル(PENDING → RUNNING → DONE)を理解し、
bq ls -j/bq show --job=true/bq cancelで追跡・操作する - INFORMATION_SCHEMA の 3 つのスコープ修飾子(project・region・dataset)を使い分け、JOBS と TABLE_STORAGE ビューで運用クエリを書く
- 高額クエリ Top10・失敗ジョブの傾向・ストレージ肥大・未使用テーブルを検出する定番クエリパターンを身につける
- クォータと上限の構造を理解し、quota exceeded / resources exceeded エラーの原因を読み解いて対処する
- リザベーションの assignment によるワークロード分離と、ラベルによるコスト配賦という組織運用の型を知る
前提: 全ハンズオンはサンドボックスで完走可・無料枠内。INFORMATION_SCHEMA クエリは 1 回あたり最低 10 MB の課金判定を受けますが、無料枠(クエリ月 1 TiB・ストレージ 10 GiB、2026-08 時点)に対して無視できる量です。
ジョブという実行単位とライフサイクル
BigQuery でクエリ・ロード・エクスポート・テーブルコピーを実行すると、そのたびにジョブが自動的に作成されます。ジョブは非同期に実行され、進捗をポーリングできる管理単位です。ジョブには 4 つの種類があります。
- query — SQL クエリの実行
- load — 外部データのロード
- extract — テーブルデータのエクスポート
- copy — テーブル・クローン・スナップショットのコピー
ジョブは常に次の 3 状態のいずれかにあります。
error_result の有無で成功・失敗に分かれる。キャンセルは PENDING・RUNNING 中だけ有効で、キャンセルされたジョブは error_result.reason = 'stopped' として DONE になる。ジョブは <project_id>:<region>.<job_id> という完全修飾 ID を持ちます。BigQuery Studio に表示される ID はこの完全形式ですが、bq コマンドの出力は短縮形式(project と location を含まない)です。ジョブの追跡は bq コマンドで一通り行えます。
# 自分のジョブを一覧(bigquery.jobs.list 権限)
bq ls --jobs=true --max_results=10
# 全ユーザーのジョブを一覧(bigquery.jobs.listAll 権限が必要)
bq ls --jobs=true --all=true --max_results=10 PROJECT_ID
# ジョブの詳細を確認
bq show --format=prettyjson --job=true JOB_ID
# 実行中・待機中のジョブをキャンセル(PENDING/RUNNING のみ対象)
bq --location=US cancel JOB_ID
ジョブ履歴はプロジェクトの全リージョン分が 6 か月間保存されます。bq ls --jobs=true は既定で自分のジョブだけを返し、--all=true(bigquery.jobs.listAll 権限が必要)を付けると全ユーザーのジョブが対象になります。
roles/bigquery.jobUser)で十分なことが多く、運用担当が全ジョブを横断的に見る必要があるなら BigQuery Resource Admin(roles/bigquery.resourceAdmin、全ジョブの一覧・メタデータ取得)、他人のジョブを止める権限まで要るなら BigQuery Admin(roles/bigquery.admin)まで踏み込みます。「実行できる」と「他人のジョブが見える」は別の権限段階だと意識してください。INFORMATION_SCHEMA を武器にする
INFORMATION_SCHEMA は BigQuery の全リソースのメタデータを SQL で問い合わせられる、読み取り専用のシステム定義ビュー群です。課金は次の通りです。
- オンデマンド課金のプロジェクトでは、INFORMATION_SCHEMA へのクエリは最低 10 MB の処理課金が発生します(実際の処理バイト数がそれ未満でも 10 MB として課金)
- 容量ベース課金のプロジェクトでは、購入済みスロットを消費します
- ストレージ料金は発生しません。ただしクエリ結果はキャッシュされないため、同じ SQL を再実行するたびに課金されます
INFORMATION_SCHEMA ビューを問い合わせるには、データセット・リージョン・プロジェクトの 3 種類の修飾子のいずれかでスコープを指定する必要があります。
リージョン修飾子は region-us のように region- の後にロケーション名を続けます。非階層的で、US マルチリージョンの修飾子は us-central1 などの単一リージョンを含みません。プロジェクト修飾子はどのビューでも併用でき、省略時はクエリを実行しているプロジェクトが対象になります。
-- プロジェクト修飾子 + リージョン修飾子 + JOBS ビュー
SELECT job_id, total_bytes_billed, total_slot_ms
FROM `PROJECT_ID`.`region-us`.INFORMATION_SCHEMA.JOBS
WHERE creation_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 DAY);
JOBS ビュー — コスト・スロット・エラーの分析
INFORMATION_SCHEMA.JOBS(別名 JOBS_BY_PROJECT。両者は同じ結果を返す同義語)は、現在のプロジェクトの全ジョブのメタデータをほぼリアルタイムで提供します。creation_time でパーティション化され、project_id と user_email でクラスタリングされているため、creation_time に絞り込むほど効率よくプルーニングされます。主なカラムは次の通りです。
job_id/job_type(QUERY・LOAD・EXTRACT・COPY)/statement_type(SELECT・INSERT・SCRIPT 等)state(PENDING・RUNNING・DONE)/error_result(reasonとmessageを持つ RECORD。成功時は NULL)total_bytes_billed/total_bytes_processed/total_slot_ms(スロットミリ秒。リトライ分も含む累積)cache_hit/referenced_tables/labels(キーバリューの配列)/user_email
このビューを問い合わせるには、プロジェクトに BigQuery User(roles/bigquery.user)と BigQuery Resource Viewer(roles/bigquery.resourceViewer)ロールが必要です(実体は bigquery.jobs.listAll と bigquery.jobs.create 権限)。全ユーザーのジョブを横断的に見る、管理者寄りのビューです。
自分のジョブだけを見るなら INFORMATION_SCHEMA.JOBS_BY_USER を使います。必要なロールは BigQuery User だけ(bigquery.jobs.list 権限)で、JOBS ビューよりずっと低い権限で済みます。
JOBS_BY_USER、「プロジェクト全体のコストを横断分析したい運用担当」には JOBS(JOBS_BY_PROJECT)と、権限の強さに応じてビューを選び分けます。JOBS は組織・フォルダ単位にも JOBS_BY_FOLDER・JOBS_BY_ORGANIZATION として拡張でき、スコープが広がるほど必要な IAM も組織階層の上位に上がります。TABLE_STORAGE ビュー — ストレージ肥大の棚卸し
INFORMATION_SCHEMA.TABLE_STORAGE(別名 TABLE_STORAGE_BY_PROJECT)は、テーブル・マテリアライズドビューごとの現在のストレージ使用量を 1 行ずつ返します。数秒〜数分の遅延はありますが、ほぼ現在値のスナップショットです。必要なロールは BigQuery Metadata Viewer(roles/bigquery.metadataViewer、実体は bigquery.tables.get / bigquery.tables.list)で、JOBS ビューよりも軽い権限で読めます。主なカラムは次の通りです。
table_schema/table_name/total_rows/total_partitionstotal_logical_bytes/active_logical_bytes(90 日未満)/long_term_logical_bytes(90 日以上)total_physical_bytes/active_physical_bytes/long_term_physical_bytes/time_travel_physical_bytes/fail_safe_physical_bytesstorage_last_modified_time(最終書き込み日時。未使用テーブルの検出に使う)
データセットが論理課金モデルなら active_logical_bytes と long_term_logical_bytes、物理課金モデルなら active_physical_bytes + fail_safe_physical_bytes と long_term_physical_bytes を使うと、月次ストレージ課金のおおまかな見積もりができます。
クォータの構造とエラーの読み方
クォータには「引き上げ可能なもの」と「変更できないシステム上限」の 2 種類があります。代表的な値は次の通りです(2026-08 時点。プロジェクト単位が既定)。
| 項目 | 既定値 | 備考 |
|---|---|---|
| オンデマンドの最大同時スロット | 2,000/プロジェクト、20,000/組織 | 組織内で複数プロジェクトが同時に高負荷だと按分される |
| ペンディングジョブ数 | 50,000/プロジェクト・リージョン | 変更不可のシステム上限 |
| キュー待ちインタラクティブクエリ | 1,000 件 | 超過分は quota エラーで弾かれる |
| キュー待ちバッチクエリ | 20,000 件 | - |
| クエリ / マルチステートメントクエリの実行時間 | 6 時間 | 最大 3 回までリトライされるため合計は 6 時間を超え得る |
| オンデマンドの CPU 使用量上限 | 256 CPU 秒 / スキャン MiB | 超過で billingTierLimitExceeded |
| ロードジョブ | 1,500/テーブル/日、100,000/プロジェクト/日 | 失敗したロードも回数に含む |
| コピージョブ | 100,000/プロジェクト/日 | リージョン跨ぎは 2,000/日、100/宛先テーブル/日 |
| 抽出(エクスポート)ジョブ | 100,000/プロジェクト/日 | 無料枠は 50 TiB/日(共有スロットプール利用時) |
| mutating DML(UPDATE・DELETE・MERGE)の同時実行 | 2 件/テーブル | 超過分はテーブルごとに最大 20 件までキュー、最大待機 7 時間 |
クォータ・上限の実測値は Google Cloud コンソールの「IAM と管理」→「割り当て」ページ、または各ジョブ種別のドキュメントに記載の「現在の使用量を表示」リンクから確認できます。上限が近いか不安なら、まずは INFORMATION_SCHEMA.JOBS で自分たちの実際のジョブ量を数えるのが早道です。
エラーが発生したら error_result.reason を見て種類を切り分けます。
error_result.reason の値ごとに対処が異なる。quotaExceeded と rateLimitExceeded はどちらも HTTP 403 だが、前者は割り当て超過、後者は短時間の過剰リクエストという別の原因を持つ。| reason | HTTP | 意味 | 対処 |
|---|---|---|---|
| quotaExceeded | 403 | プロジェクトのクォータ・カスタムクォータ・無料枠の超過 | message プロパティで詳細確認、サポートへ増枠依頼、カスタムクォータの見直し |
| rateLimitExceeded | 403 | 短時間に送信したリクエスト数が過剰 | 指数バックオフでリクエスト頻度を落とす |
| resourcesExceeded | 400 | ジョブがメモリ等のシステムリソースを過剰消費 | JOIN 順序・中間結果サイズなどクエリ自体を見直す |
| billingTierLimitExceeded | 400 | オンデマンドクエリの CPU 使用量がスキャン量に対し過大(billingTier > 100) | 非効率なクロスジョインを最適化するか、容量ベース(editions)へ移行 |
| responseTooLarge | 403 | クエリ結果が最大レスポンスサイズを超過 | LIMIT の追加、ORDER BY の見直し、宛先テーブルへの書き出し |
リザベーションと組織運用の型
継続的に大きなワークロードを抱えるなら、オンデマンド課金ではなくリザベーション(スロットの予約)を使い、プロジェクトを予約にassignment(割り当て)します。assignment には job_type を指定でき、同じ予約でも用途別に振る舞いを分けられます。代表的な job_type は QUERY(既定値)・CONTINUOUS(継続クエリ)・PIPELINE(ロード・エクスポート・コピー等のバックグラウンドジョブ)・BACKGROUND・ML_EXTERNAL です。
-- プロジェクトを予約に割り当てる(job_type で用途を分ける)
CREATE ASSIGNMENT
`ADMIN_PROJECT_ID.region-LOCATION.RESERVATION_NAME.ASSIGNMENT_ID`
OPTIONS (
assignee = 'projects/PROJECT_ID',
job_type = 'PIPELINE'
);
割り当て直後にクエリを実行すると、反映まで最大 5 分ほどオンデマンド課金のまま実行される場合があります。またプレビュー機能として、予約に対するプロジェクトキャップ(scheduling_policy_max_slots / scheduling_policy_concurrency)を CREATE ASSIGNMENT の追加オプションで設定でき、同じ予約を使うプロジェクトごとにスロット消費や同時実行数を個別に制限できます。
組織運用では、この技術要素を次のような型に落とし込みます。
- 環境分離 — dev / staging / prod をプロジェクト単位で分け、クォータ超過や事故のブラスト半径をプロジェクトの外に漏らさない
- 命名規約 — プロジェクト ID・データセット名・予約名に環境や用途を機械的に判別できる接頭辞を持たせ、INFORMATION_SCHEMA での横断集計をしやすくする
- ラベルによるコスト配賦 — データセット・テーブル・予約・ジョブに
team:analyticsのようなラベルを付け、請求データやこの章で書く INFORMATION_SCHEMA クエリで部門別に費用を按分する
ラベルはキー・値ともに小文字英数字とアンダースコア・ダッシュのみ(国際文字も可)で、キーは 1〜63 文字、値は 0〜63 文字、1 リソースにつき最大 64 個まで付けられます。キーはリソース内で一意である必要があります。
公開データセットに数回クエリを実行し、そのジョブ履歴を INFORMATION_SCHEMA.JOBS で分析します。サンドボックスで完走可・無料枠内(合計でも数 MB 程度)。
- 演習用データセットを作成し、Shakespeare の公開データセットに 2 種類のクエリを投げます。
bq mk --location=US --dataset PROJECT_ID:handson_ch17
-- 処理: 約 6 MB
SELECT corpus, SUM(word_count) AS total_words
FROM `bigquery-public-data.samples.shakespeare`
GROUP BY corpus
ORDER BY total_words DESC
LIMIT 5;
-- 処理: 約 6 MB
SELECT word, word_count
FROM `bigquery-public-data.samples.shakespeare`
WHERE corpus = 'hamlet'
ORDER BY word_count DESC
LIMIT 10;
- 直近のジョブを課金バイト数の多い順に並べます(INFORMATION_SCHEMA クエリ自体は最低 10 MB 課金)。
SELECT
job_id,
creation_time,
total_bytes_billed,
total_slot_ms,
cache_hit
FROM `region-us`.INFORMATION_SCHEMA.JOBS
WHERE job_type = 'QUERY'
AND state = 'DONE'
AND creation_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 DAY)
ORDER BY total_bytes_billed DESC
LIMIT 10;
期待される出力: 直前に実行した 2 件のクエリが total_bytes_billed の大きい順に並びます(このビューには自分の全履歴が対象期間分含まれるため、過去に実行したジョブが多いほど行数も増えます)。cache_hit が true の行は再実行時の 2 回目以降で見られます。
後片付け:
bq rm -r -f -d PROJECT_ID:handson_ch17
サイズの異なる 2 つのテーブルを作り、TABLE_STORAGE でストレージ使用量と最終更新時刻を確認します。サンドボックスで完走可・無料枠内(合計でも数 MB 程度)。ハンズオン 17-1 のデータセットを削除済みの場合は再作成してください。
- 大きさの異なる 2 つのテーブルを作成します。
bq mk --location=US --dataset PROJECT_ID:handson_ch17
CREATE OR REPLACE TABLE `PROJECT_ID.handson_ch17.hamlet_words` AS
SELECT word, word_count
FROM `bigquery-public-data.samples.shakespeare`
WHERE corpus = 'hamlet';
CREATE OR REPLACE TABLE `PROJECT_ID.handson_ch17.all_words_snapshot` AS
SELECT word, corpus, word_count
FROM `bigquery-public-data.samples.shakespeare`;
- TABLE_STORAGE でサイズと最終更新時刻を確認します(TABLE_STORAGE はデータセット修飾子に対応していないため、リージョン修飾子 +
table_schemaでの絞り込みが必要です)。
SELECT
table_name,
total_rows,
ROUND(total_logical_bytes / POW(1024, 2), 3) AS logical_mb,
ROUND(active_logical_bytes / POW(1024, 2), 3) AS active_mb,
storage_last_modified_time
FROM `region-us`.INFORMATION_SCHEMA.TABLE_STORAGE
WHERE table_schema = 'handson_ch17'
ORDER BY total_logical_bytes DESC;
期待される出力: all_words_snapshot が hamlet_words より大きい 2 行。未使用テーブルを検出する定番パターンは、storage_last_modified_time を現在時刻と比較する条件を WHERE に足すだけです(例: AND storage_last_modified_time < TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 90 DAY))。
後片付け:
bq rm -r -f -d PROJECT_ID:handson_ch17
存在しないテーブルを参照してジョブを 1 件失敗させ、INFORMATION_SCHEMA.JOBS で失敗傾向を分析します。サンドボックスで完走可・無料枠内(失敗クエリはスキャンなしで課金対象外)。ハンズオン 17-1/17-2 のデータセットを削除済みの場合は再作成してください。
- 存在しないテーブルを参照し、意図的にジョブを失敗させます。
bq mk --location=US --dataset PROJECT_ID:handson_ch17
-- 存在しないテーブルを参照するため notFound で失敗する(スキャンなし・課金なし)
SELECT * FROM `PROJECT_ID.handson_ch17.does_not_exist_yet`;
- 失敗ジョブの傾向を
error_result.reasonでグルーピングし、直近の失敗の詳細も確認します。
SELECT
job_type,
state,
error_result.reason AS error_reason,
COUNT(*) AS job_count
FROM `region-us`.INFORMATION_SCHEMA.JOBS
WHERE creation_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 DAY)
GROUP BY job_type, state, error_reason
ORDER BY job_count DESC;
-- 直近の失敗ジョブの詳細(reason と message)
SELECT job_id, error_result.reason, error_result.message
FROM `region-us`.INFORMATION_SCHEMA.JOBS
WHERE state = 'DONE' AND error_result IS NOT NULL
ORDER BY creation_time DESC
LIMIT 5;
期待される出力: 1 つ目のクエリで error_reason = 'notFound' の行が 1 件以上表示されます。2 つ目のクエリでは、そのジョブの message に「Not found: Table ...」という具体的な原因が入っています。quotaExceeded や resourcesExceeded が出た場合も同じ 2 段構え(まず reason で分類 → message で詳細確認)で読み解きます。
後片付け:
bq rm -r -f -d PROJECT_ID:handson_ch17
データセットとクエリジョブにラベルを付け、ラベル別にコストを集計します。サンドボックスで完走可・無料枠内。ハンズオン 17-1〜17-3 のデータセットを削除済みの場合は再作成してください。
- データセットにラベルを付け、ラベル付きのクエリジョブを実行します。
bq mk --location=US --dataset PROJECT_ID:handson_ch17
bq update --set_label team:analytics PROJECT_ID:handson_ch17
bq query --use_legacy_sql=false \
--label team:analytics \
--label env:handson \
'SELECT corpus, COUNT(*) AS row_count
FROM `bigquery-public-data.samples.shakespeare`
GROUP BY corpus'
ジョブのラベルは 実行時にしか付けられません。実行済みのジョブに後からラベルを追加・変更することはできない点に注意してください(データセットやテーブルのラベルは後から bq update --set_label で変更できます)。
- ラベルをキーに、ジョブのコストを集計します。
SELECT
label.value AS team,
COUNT(*) AS job_count,
SUM(total_bytes_billed) AS total_bytes_billed
FROM `region-us`.INFORMATION_SCHEMA.JOBS,
UNNEST(labels) AS label
WHERE label.key = 'team'
AND creation_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 DAY)
GROUP BY team
ORDER BY total_bytes_billed DESC;
期待される出力: team = analytics の行に、先ほど実行したジョブの total_bytes_billed が集計されます。同じパターンで department や cost_center ラベルを使えば、組織のコスト配賦の単位でそのまま集計できます。
後片付け:
bq rm -r -f -d PROJECT_ID:handson_ch17
つまずきポイント
INFORMATION_SCHEMA.JOBS だけを書くとエラーになります。また、クエリの実行ロケーションと修飾子のロケーションが一致していないと Table myproject:region-us.INFORMATION_SCHEMA.[VIEW] not found in location US のようなエラーになります。creation_time(パーティショニングカラム)による絞り込みしか見積もりに反映せず、project_id や user_email(クラスタリングカラム)の絞り込みは加味されません。実際の処理バイト数は見積もりよりかなり少ないことが多いので、慌てて代替クエリを探す前に実際に実行して確認してください。JOBS(JOBS_BY_PROJECT)はプロジェクト全体を横断するために bigquery.jobs.listAll が必要ですが、JOBS_BY_USER は自分のジョブしか返さない代わりに bigquery.jobs.list だけで済みます。「権限エラーは出ていないのに他人のジョブが 1 件も出てこない」ときは、ビュー選択を疑ってください。WHERE table_schema = 'データセット名' で行ってください。理解度チェック
Q1. INFORMATION_SCHEMA ビューを問い合わせるとき、必ず指定しなければならないものは何ですか?
データセット修飾子・リージョン修飾子・プロジェクト修飾子のいずれかによるスコープ指定です。どれも付けずに素の INFORMATION_SCHEMA.VIEW だけを書くとエラーになります。プロジェクト修飾子は他の 2 つと併用でき、省略時は実行中のプロジェクトが対象になります。
Q2. INFORMATION_SCHEMA.JOBS と JOBS_BY_USER の違いを、必要な権限の観点から説明してください。
JOBS(JOBS_BY_PROJECT の同義語)はプロジェクト内の全ユーザーのジョブを対象とし、bigquery.jobs.listAll を含む BigQuery User + BigQuery Resource Viewer ロールが必要です。JOBS_BY_USER は実行者自身のジョブだけを返す代わりに、BigQuery User ロール(bigquery.jobs.list)だけで問い合わせられます。
Q3. quotaExceeded と resourcesExceeded の違いは何ですか?
quotaExceeded(HTTP 403)はプロジェクトのクォータ・カスタムクォータ・無料枠を使い切ったことを示し、message プロパティで超過した項目を確認してから増枠やカスタムクォータの調整で対処します。resourcesExceeded(HTTP 400)はクォータとは無関係に、個々のジョブがメモリなどのシステムリソースを使いすぎたことを示し、クエリ自体(JOIN 順序や中間結果のサイズ)を見直して対処します。
Q4.(シナリオ)ETL 用の大量ロードジョブが夜間バッチで走ると、日中に動かしているダッシュボードの BI クエリの応答が遅くなる、というスロット競合が起きている。最も効果的な対策は?
A. BI クエリのクォータを引き上げる B. ETL 用プロジェクトと BI 用プロジェクトを別のリザベーションに assignment し job_type でも分離する C. INFORMATION_SCHEMA.JOBS で監視だけ強化する D. ETL のロードジョブの実行時間帯を記録する
B。 リザベーションを分け、ETL プロジェクトには job_type=PIPELINE、BI プロジェクトには job_type=QUERY で assignment すれば、スロットプールそのものが分離され競合が起きなくなります。A はオンデマンドのクォータを増やすだけで根本のスロット共有は解消しません。C・D は現状把握にはなりますが、競合そのものへの対策にはなりません。
Q5.(シナリオ)オンデマンドプロジェクトで実行したクエリが billingTierLimitExceeded で失敗した。ジョブの詳細を見ると、行数の少ない複数テーブルを条件を絞らずに JOIN していた。最適な対処は?
A. maximum_bytes_billed を上げる B. カスタムクォータを緩和する C. 非効率なクロスジョインになっていないか JOIN 条件を見直す D. LIMIT 句を追加する
C。 billingTierLimitExceeded はスキャン量に対して CPU 使用量が過大なときに発生し、典型的な原因は不正確な JOIN 条件による意図しないクロスジョインです。A・B はバイト数やクォータの上限緩和であり CPU 使用量の問題には無関係です。D は結果行数を減らすだけで、JOIN 自体の計算量は変わりません。
まとめと次章へ
- ジョブは PENDING → RUNNING → DONE で進み、
bq ls -j/bq show --job=true/bq cancelで追跡・操作できる - INFORMATION_SCHEMA はデータセット・リージョン・プロジェクトの 3 修飾子でスコープを指定する読み取り専用ビュー群。JOBS は高額クエリ・失敗傾向、TABLE_STORAGE はストレージ肥大・未使用テーブルの定番クエリに使う
- JOBS と JOBS_BY_USER、ORGANIZATION/FOLDER/PROJECT スコープは必要な IAM 権限の強さが異なるので、見たい範囲に応じてビューを選ぶ
- エラーは
error_result.reasonで種類を切り分け、messageで詳細を確認する。quotaExceeded・rateLimitExceeded・resourcesExceeded・billingTierLimitExceeded は原因も対処もそれぞれ異なる - リザベーションの assignment は job_type で用途別にワークロードを分離でき、ラベルは組織のコスト配賦をそのまま INFORMATION_SCHEMA クエリに落とし込める
- 料金モデルの詳細は第 7 章(料金モデルとコスト管理)、監査ログによる「誰が何を読んだか」の追跡は第 16 章(セキュリティとガバナンス)を参照