BigQueryのObjectRefは、Cloud Storageに置いた画像・PDF・音声などのファイルを、標準テーブルの1列として持つための参照型です。ファイル本体は動かさず、商品マスタや請求データの行に「どのファイルのどの版か」を紐づけ、そのままAI.GENERATEなどのAI関数に渡せます。2026年10月22日付の公式ブログでGA(一般提供)が告知され、プレビュー期の解説記事とは書き方が変わりました。この記事では、構造、作り方、権限設定、上限と料金、採用を見送る場面までを、2026年10月24日時点の公式ドキュメントに沿ってSQL例付きで説明します。
まとめ:ObjectRefはファイルを表の列にする参照型で、先に決めるのは権限方式
ObjectRefの実体はuri・version・authorizer・detailsの4項目を持つSTRUCTです。ファイルの中身は持たず、場所と世代番号とメタデータだけを保存します。作り方は、URIの列があればOBJ.MAKE_REF、その場でバケットを探すならOBJ.LIST、継続的に一覧を保つならオブジェクトテーブルのref列、の3通りです。
設計で最初に決めるのは、ファイルを誰の権限で読むかです。1プロジェクトの小さなチームなら、実行ユーザー自身の権限で読む直接アクセスで足ります。データ置き場と分析を別プロジェクトに分けている組織では、接続(Cloud リソース接続)に読み取りを任せる委任アクセスを選びます。ただしVPC Service Controlsの境界内では、委任アクセスをAI関数で使えません。
費用が大きく動くのはOBJ関数ではなく、ファイルの中身をGeminiに読ませるAI関数の段階です。BigQueryの外で推論している構成なら、無理に入れる必要はありません。
ObjectRefの4項目の構造とオブジェクトテーブルから変わった点
ObjectRefの公式ガイドは、ObjectRefを「Cloud Storageのオブジェクトを参照する、定義済みスキーマのSTRUCT型」と説明しています。受け取れるのはOBJ関数、AI関数、Pythonのユーザー定義関数(UDF)です。
必須なのはuriだけで、ほかはNULLを許します。
| 項目 | 型 | 入る値 |
|---|---|---|
| uri | STRING(必須) | Cloud StorageのURI |
| version | STRING | 世代番号(generation) |
| authorizer | STRING | 委任アクセス用の接続ID(NULL=直接) |
| details | JSON | サイズ・MIME型などかエラー情報 |
実務で効くのはversionです。同じパスにファイルを上書きすると、Cloud Storageの世代番号は変わります。ObjectRefはこの番号を追うため、行を書き込んだ時点の版を後から参照でき、推論結果を再現しやすいと公式ブログは説明しています。請求書PDFが差し替えられても、どの版から金額を抜き出したかを行単位で示せる。ここがURI文字列だけを持つ設計との違いです。
オブジェクトテーブルのref列と標準テーブルのObjectRef列の違い
BigQueryには以前から、バケット内のファイル一覧を読み取り専用の表として見せるオブジェクトテーブルがあります。列はCloud Storageのメタデータに固定され、商品名や取引先IDのような業務の列は足せません。業務データと結合すると、ファイルへの手がかりはURI文字列だけになっていました。
ObjectRefは、この参照情報を標準テーブルの任意の列に持ち運べる型です。商品マスタにproduct_image列を置けば、JOINやCREATE TABLE AS SELECTを経ても参照が失われません。オブジェクトテーブルにもref列が追加されており、そこから標準テーブルへ写す使い方が公式に案内されています。
2025年5月のプレビューから2026年10月GAまでに変わった書き方
検索で見つかる解説の多くはプレビュー期のもので、AI関数に渡す前にOBJ.GET_ACCESS_URLで署名付きURLを作る書き方になっています。BigQueryのリリースノートで、変わった時期を確認できます。
| 日付 | 変更内容 | 書き方への影響 |
|---|---|---|
| 2025年5月12日 | ObjectRefがプレビュー提供 | GET_ACCESS_URL経由で渡す |
| 2026年3月31日 | OBJ関数が直接アクセスにも対応 | 接続なしで自分の権限で読める |
| 2026年6月12日 | AI関数がObjectRefを直接受理 | GET_ACCESS_URLが不要になる |
| 2026年9月30日 | OBJ.LIST関数がGA | オブジェクトテーブルなしで一覧できる |
| 2026年10月22日 | ObjectRefとマルチモーダル分析がGA | 全エディションとオンデマンドで利用可 |
古い記事のSQLを写すと、不要な署名付きURLの生成が残ります。署名付きURLは後述のVPC Service Controlsで拒否される原因にもなるので、AI関数へはref列をそのまま渡してください。
ObjectRefを作るSQL:OBJ.LISTとOBJ.MAKE_REFと配列列
バケット名・データセット名・接続名は置き換えて使います。関数の仕様はObjectRef関数のリファレンスに基づきます。
OBJ.LISTで請求書PDFを一覧しAI.GENERATEで列に抜き出すSQL
URIを持つ表がまだ無い段階では、OBJ.LISTでバケットを直接一覧するのが早道です。戻り値にはuri・content_type・size・generationなどのメタデータ列と、ObjectRefのref列が並びます。
-- 10月分の請求書PDFから、取引先名と税込合計を列として取り出して保存する
CREATE OR REPLACE TABLE `myproject.ap.invoice_extract_202610` AS
SELECT
uri,
generation,
ref,
AI.GENERATE(
('この請求書から取引先名と税込合計金額を抜き出してください。', ref),
output_schema => 'vendor_name STRING, total_amount INT64'
) AS extracted
FROM OBJ.LIST('gs://my-bucket/invoices/2026-10/*.pdf');
ワイルドカードの*は1つのパスに1個までです。末尾がスラッシュのURIや、スラッシュが連続するURIはエラーになるため、拡張子まで書くのが確実です。URIにCONCATやスカラーサブクエリは使えません。第2引数の接続を省いたこの例は、実行ユーザーの権限で読む直接アクセスになります。
OBJ.LISTは探索や単発のETL向けです。届き続けるファイルを継続して追う用途には、公式もオブジェクトテーブルを勧めています。
既存の商品テーブルにOBJ.MAKE_REFでObjectRef列を足す手順
画像のURIを文字列で持つ商品マスタがあるなら、OBJ.MAKE_REFでその列からObjectRefを作れます。ObjectRef列の仕様が定める列の型はSTRUCT<uri STRING, version STRING, authorizer STRING, details JSON>です。表を作り直さないなら、列を足してからUPDATEで埋めます。
-- 1. ObjectRef形式の列を追加する
ALTER TABLE `myproject.shop.products`
ADD COLUMN image_ref STRUCT<uri STRING, version STRING, authorizer STRING, details JSON>;
-- 2. 文字列のURI列から、接続付きのObjectRefを作って埋める
UPDATE `myproject.shop.products`
SET image_ref = OBJ.MAKE_REF(image_uri, 'us.media_conn')
WHERE image_uri != '';
-- 3. 商品の属性と画像を1回の呼び出しで渡し、説明文の下書きを作る
SELECT
product_id,
AI.GENERATE(
('次の商品名と画像から、通販サイト用の説明文を120字で書いてください。商品名: ', product_name, image_ref)
).result AS draft_description
FROM `myproject.shop.products`
WHERE image_ref IS NOT NULL
LIMIT 10;
2026年3月31日の更新以降、OBJ.MAKE_REFはCloud Storageから最新のメタデータを取得してdetailsに入れます。大量の行を一度に埋めるとそのぶん取得が走るため、オブジェクトテーブルがあればref列とURIで結合して写すほうが効率的、というのが公式の案内です。手順3のLIMIT 10は、AI関数の課金が行数に比例するためのもの。トークンの見積もりと日次上限の設定はBigQuery AI関数の使い方とトークンクォータで説明しています。
動画から切り出した画像をARRAY型のObjectRef列に順番どおり保存する
ObjectRefは配列でも持てます。動画から切り出した静止画や、1件の申込に添付された複数の書類を、1行の配列列にまとめる使い方です。並び順はARRAY_AGGのORDER BYで保ち、取り出すときはUNNESTのWITH OFFSETで復元するよう公式は案内しています。
-- 切り出し画像(動画IDごとのフォルダに連番で保存済み)を、動画単位の配列にまとめる
CREATE OR REPLACE TABLE `myproject.media.video_frames` AS
SELECT
REGEXP_EXTRACT(uri, r'frames/([^/]+)/') AS video_id,
ARRAY_AGG(ref ORDER BY uri) AS frame_refs
FROM OBJ.LIST('gs://my-bucket/frames/*.jpg', 'us.media_conn')
GROUP BY video_id;
-- 配列から1枚ずつ取り出し、元の順番(frame_no)を付けて戻す
SELECT video_id, frame_no, frame.uri
FROM `myproject.media.video_frames`,
UNNEST(frame_refs) AS frame WITH OFFSET AS frame_no
ORDER BY video_id, frame_no;
配列はそのままAI関数に渡せます。公式ブログには、正規のログイン画面と疑わしい画面のスクリーンショット2枚を配列にして、1回の呼び出しで比較させる例があります。連番の桁がそろっていないとORDER BY uriの並びが崩れるので、切り出し時に0001.jpgのようにゼロ埋めしてください。
直接アクセスと委任アクセスの権限設定:接続とIAMロールの付け方
ObjectRefを受け取った関数は、Cloud Storageのファイルを誰かの権限で読みに行きます。authorizerがNULLなら実行ユーザー本人の権限で読む直接アクセス、接続IDが入っていれば接続のサービスアカウントに読ませる委任アクセスです。
直接アクセスで動かす3つの条件と同一プロジェクト内バケットに限る制約
直接アクセスは準備が少なく、検証の初手に向いています。条件は、実行ユーザーがファイルの読み取り権限を持つこと、接続なしでAI.GENERATE・AI.IF・AI.SCORE・AI.CLASSIFYを呼ぶための追加権限を持つこと、バケットがジョブを実行するプロジェクトと同じであることの3つです。
見落とされがちなのは3つ目。データ置き場を共有プロジェクトに集めている組織では、直接アクセスで他プロジェクトのバケットは読めません。権限が足りなくてもAI関数はクエリを失敗させず、status列にpermission deniedを書いて先へ進みます。件数だけで成功と判断せず、statusを集計して確認してください。
委任アクセスの準備:接続のサービスアカウントとObjectRef Reader
委任アクセスでは、データ管理者が接続を1回だけ用意し、利用者には接続を使う権限だけを配ります。分析者はバケットの権限を持たないまま、ObjectRef経由でファイルを読める仕組みです。Cloud リソース接続の作成手順とBigQueryのIAMロール一覧に沿ったコマンドは次のとおりです。
# 1. USロケーションにCloud リソース接続を作る
bq mk --connection --location=US --project_id=myproject \
--connection_type=CLOUD_RESOURCE media_conn
# 2. 接続に紐づくサービスアカウントを確認する(出力のserviceAccountId)
bq show --connection myproject.us.media_conn
# 3. そのサービスアカウントにバケットの読み書きを許可する
gcloud storage buckets add-iam-policy-binding gs://my-bucket \
--member=serviceAccount:SERVICE_ACCOUNT_ID \
--role=roles/storage.objectUser
# 4. 分析者のグループに、接続経由でObjectRefを読む権限を付ける
gcloud projects add-iam-policy-binding myproject \
--member=group:ANALYST_GROUP_EMAIL \
--role=roles/bigquery.objectRefReader
手順4のObjectRef Reader(roles/bigquery.objectRefReader)はbigquery.objectRefs.readだけを持つロールで、付与できる最小単位は接続です。接続が複数あるなら、プロジェクト単位ではなく接続ごとに付けると範囲を絞れます。書き込みまで任せる場合はObjectRef Admin(roles/bigquery.objectRefAdmin)です。読むだけなら、手順3は読み取り専用のStorage Object Viewerでも足ります。
接続のロケーションとクエリのロケーションは、バケットのリージョンと両立している必要があります。データセットのロケーションを後から変えられない点はBigQueryのデータセット設計で扱っています。
VPC Service Controls境界内で委任アクセスが失敗する理由と回避策
境界内のプロジェクトでは、委任アクセスのObjectRefをAI関数に渡すと失敗します。委任アクセスはファイルの署名付きHTTPS URLを作ってモデルに渡す仕組みで、署名付きURLは境界を越えられないためです。statusには、Agent Platform(旧Vertex AI)を制限している場合はHTTP links are not supported for requests restricted by VPCSC.、Cloud Storageを制限している場合はCannot fetch content from the provided URLが入ります。
オブジェクトテーブルのref列は作成時の接続が必ずauthorizerに入るため、境界内では常にこのエラーです。公式の回避策は、OBJ.MAKE_REF(uri)を引数1つで呼んで直接アクセスのObjectRefとして渡すこと。署名付きURLを作らずにURIをモデルへ送るので、境界の内側で処理が完結します。金融・医療など境界を張っている環境では、設計段階で直接アクセスを前提にしてください。
本番運用で詰まりやすいObjectRefの接続数上限・料金・エラー検出の実装
本番へ移るときに問題になるのは、上限値、課金の発生箇所、失敗した行の拾い方です。上限と料金はマルチモーダルデータ分析の概要に載っています。
接続20個・参照先プロジェクト5つの上限と接続を集約する設計
ObjectRef経由でファイルを読むクエリには、2つの上限があります。クエリがオブジェクトを読むプロジェクトとリージョンで使える接続は20個まで、クエリを実行するプロジェクト以外に参照できるプロジェクトは5つまでです。
部署ごと・バケットごとに接続を作ると、20個は意外に早く埋まります。読み取り用の接続を1つにまとめて複数バケットにroles/storage.objectViewerを付け、利用者の絞り込みはObjectRef Readerを付ける相手で行えば、数は増えません。authorizerにプロジェクト名を書かない場合、接続はObjectRefを保存するテーブルのプロジェクトか、クエリを実行するプロジェクトに必要です。別プロジェクトの接続はmyproject.us.media_connの3階層で書きます。
OBJ関数はメタデータだけを読みAI関数の段階で費用が出る料金構造
ObjectRef列の保存はテーブルのストレージ料金に、ObjectRefを読むクエリはBigQueryのコンピュート料金に含まれます。OBJ.LISTやOBJ.GET_READ_URLはメタデータだけを処理し、ファイルの中身は読みません。
費用が跳ねるのは、ObjectRefをAI.GENERATEやAI.IFに渡してファイルの中身をGeminiに読ませる段階で、Agent Platformの料金として請求されます。Python UDFで加工すればPython UDFの料金が、変換結果をファイルに書き出せばCloud Storageの料金が加わる構造です。ワイルドカードを広く書いたままAI関数に渡すと、想定外のファイルまで推論にかかります。先にOBJ.LISTだけを実行して件数とsizeの合計を確かめましょう。BigQuery側の課金体系はBigQueryの料金で整理しています。
details.errorsとstatus列で権限不足や削除済みファイルを拾うSQL
エラーは、クエリ全体の失敗と、結果の中に書かれるエラーの2通りで返ります。後者はクエリが成功して見えるので、定期処理では毎回拾う仕組みが要ります。
-- ObjectRef自体のエラー(URIや世代番号が存在しない、接続の権限がない)
SELECT
image_ref.uri,
JSON_VALUE(image_ref.details.errors[0].message) AS error_message,
JSON_VALUE(image_ref.details.errors[0].source) AS error_source
FROM `myproject.shop.products`
WHERE image_ref.details.errors IS NOT NULL;
-- AI関数の結果に残ったエラー(権限不足・クォータ超過など)を件数で確認する
SELECT extracted.status, COUNT(*) AS rows_count
FROM `myproject.ap.invoice_extract_202610`
GROUP BY extracted.status;
details.errorsの各要素はcode・message・source(エラーを出した関数名)を持ちます。代表例は、URIや世代番号が存在しないオブジェクトエラーと、接続が無いか利用権限が無い認可エラーです。ライフサイクルルールで自動削除するバケットでは、削除の周期とテーブルの保持期間を合わせないと、古い行が順にエラー行へ変わっていきます。
ObjectRefを採用する場面と、オブジェクトテーブルや個別実装を残す場面
ObjectRefは新しい型ですが、既存の構成をすべて置き換えるものではありません。判断の分かれ目は、ファイルと業務データの行を結び付けたまま扱う必要があるかどうかです。
ObjectRef列を標準テーブルに持つべき条件:ファイルと属性の結合
次の条件に当てはまるなら、標準テーブルにObjectRef列を持つ設計を採ります。
- 商品・請求・問い合わせなどの業務データの行ごとに、対応するファイルが1つ以上ある
- ファイルの中身を生成AIで読み、結果を同じ行の列として残したい
- どの版のファイルから抜き出した値かを、後から説明できる必要がある
- 分析者にバケットの権限を渡さず、テーブルの共有だけで済ませたい
4つ目は委任アクセスの効果で、データ管理者がObjectRef入りの表を共有すれば、分析者は元のバケットの権限なしでファイルを分析できます。BigQuery Conversational Analyticsも2026年3月からObjectRefに対応し、表の行と画像・PDFをまとめて自然言語で問い合わせられるようになりました。
採用を見送る場面:境界内運用・BigQuery外の推論・頻繁な上書き
次の3つに当てはまる場合は、ObjectRef列を作らないか、範囲を絞ります。
1つ目は、ファイルの処理をBigQueryの外で完結させている構成です。Cloud Run上の独自OCRや外部のAI APIで結果を出し、テキストだけをBigQueryに入れているなら、参照列を読む関数がありません。URI文字列の列で十分です。
2つ目は、同じパスへの上書きが頻繁なファイル。ObjectRefは書き込み時点の世代番号を保持するため、毎時上書きされるダッシュボード画像などでは、古い版を指す行やエラー行がすぐに積み上がります。この用途にはOBJ.LISTでその都度一覧するほうが合っています。
3つ目は、VPC Service Controlsの境界内で、組織の方針として委任アクセスしか認めていない環境です。AI関数にObjectRefを渡す経路が成り立たず、主な利点が使えません。既存のオブジェクトテーブルとリモート関数の構成を残してください。
業務テーブルにどの粒度でファイル参照を持たせるか、接続と権限をどう分けるかは、テーブル設計の段階で決めておくと後戻りが減ります。既存データベースからの移行と合わせて設計を見直す場合は、データベース設計・移行支援でご相談いただけます。
BigQuery ObjectRefの使い方と料金・権限についてよくある質問
2026年10月24日時点の公式ドキュメントをもとに答えます。
ObjectRefを使うとファイルはBigQueryにコピーされますか?
コピーされません。ObjectRefが保存するのはURI・世代番号・接続ID・メタデータのJSONだけで、ファイル本体はCloud Storageに残ります。公式ブログはこれを「ゼロコピー」の構成と呼び、両者は独立して変更できるという説明です。テーブルの行を消してもファイルは消えず、逆にファイルを消すと、参照する行は次の処理でエラーになります。
ObjectRefとオブジェクトテーブルはどちらを使えばよいですか?
両方を組み合わせるのが基本です。オブジェクトテーブルはバケットの一覧を継続して保つ読み取り専用の表で、各行にref列(ObjectRef)を持ちます。業務データと結び付ける場合は、オブジェクトテーブルのrefをURIで結合して標準テーブルの列に写します。一覧を一度だけ取りたいときはOBJ.LIST、URIの列が既にあるときはOBJ.MAKE_REFと使い分けてください。
OBJ.GET_ACCESS_URLはもう不要ですか?
AI関数に渡す目的では不要です。2026年6月12日のリリースで、AI関数はObjectRefを直接受け取れるようになりました。OBJ.GET_ACCESS_URLは、BigQueryの外のアプリケーションにファイルの読み取りURLや書き込みURLを渡したいときに使います。有効期限は30分から6時間の間で指定でき、既定は6時間です。この関数は委任アクセスが前提のため、authorizer付きのObjectRefが必要です。
ObjectRefはどの料金プランで使えますか?
公式ブログによると、すべてのBigQueryエディションとオンデマンド料金で利用できます。ObjectRef自体に専用の料金は無く、列の保存はストレージ料金、クエリはコンピュート料金の中で扱われる仕組みです。ファイルの中身をGeminiに読ませるAI関数を使うと、Agent Platformのトークン料金が別に請求されます。検証ではAI関数を呼ぶ行数をLIMITで絞ってから広げてください。
PythonからObjectRefを扱えますか?
扱えます。BigQuery DataFramesでオブジェクトテーブルを読み込むとマルチモーダルなDataFrameになり、画像やPDFを生成AIのメソッドに渡せる形です。SQL側でもObjectRefをPython UDFに渡し、OpenCVなどのライブラリでファイルを移動せずに加工できると公式ブログは紹介しています。この場合はBigQuery本体とは別にPython UDFの料金が加わります。
関連記事
- BigQuery AI関数の使い方:AI.GENERATEの構文とAI.AGG・AI.TRANSLATE・AI.CHUNK_DOCUMENT、トークンクォータによるコスト管理【2026年10月】:ObjectRefを渡す先のAI関数の書き方と、トークン上限の決め方に。
- BigQueryとは:サーバーレスDWHの仕組み・料金・できないことと採用判断:BigQuery自体の仕組みと採用判断から確認したいときに。
- Cloud Storage(GCS)とは?仕組み・4つのストレージクラスとS3との違いを実装者目線で解説:ObjectRefが指すファイル置き場の設計に。
- BigQueryのCREATE TABLE:パーティション指定とMERGEの実装指針:ObjectRef列を持つ表を作り直す・更新する操作の基本に。
- BigQueryのデータセット設計:ロケーション不可逆・層別分割・権限分離の実装指針:接続やバケットとロケーションをそろえる設計に。