📸 BigQuery スナップショットデコレータ

過去の特定時点のテーブルデータにアクセス

📖 スナップショットデコレータとは

🎯 概要

スナップショットデコレータ(Snapshot Decorator)は、過去の特定時点のテーブルの状態を参照するためのBigQuery機能です。 テーブル名に@記号と時刻を追加することで、過去7日間以内の任意の時点のデータにアクセスできます。

基本構文

`project.dataset.table@TIMESTAMP`

タイムスタンプの指定方法:
  • @-3600000 - 相対時間(ミリ秒): 1時間前
  • @1234567890000 - Unixエポック(ミリ秒)
  • @'2024-12-05 10:30:00' - 絶対時刻(タイムゾーンはUTC)

Time Travel: 過去7日間のデータにアクセス

シナリオ例: 12/5 15:00に、過去のデータ状態を参照
12/5 8:00
(7日前)
保持期間開始
12/5 10:00
データ更新
12/5 11:30
削除実行
12/5 13:00
新規挿入
12/5 15:00
(現在)
クエリ実行
@10:00
10時時点
@11:30
削除前
@13:00
挿入後
✅ できること:
  • 過去7日間の任意の時点のデータを参照
  • 誤って削除したデータの復元
  • 特定時点でのデータ状態の確認
  • 変更前後の比較分析

💻 基本的な使い方

1. 相対時間指定(ミリ秒)

-- 1時間前のデータを参照(3600秒 = 3,600,000ミリ秒) SELECT * FROM `project.dataset.sales@-3600000` WHERE region = 'APAC' -- 24時間前のデータ SELECT * FROM `project.dataset.sales@-86400000` -- 24 * 60 * 60 * 1000 -- 30分前のデータ SELECT * FROM `project.dataset.sales@-1800000` -- 30 * 60 * 1000

2. 絶対時刻指定

-- 特定の日時のデータを参照(UTC) SELECT * FROM `project.dataset.sales@'2024-12-05 10:30:00'` WHERE product_id = 12345 -- 日付のみ指定(00:00:00 UTCとして扱われる) SELECT * FROM `project.dataset.sales@'2024-12-04'`

3. Unixエポック(ミリ秒)

-- Unixタイムスタンプで指定 SELECT * FROM `project.dataset.sales@1733400000000` -- 現在のタイムスタンプを取得して計算 DECLARE snapshot_time INT64; SET snapshot_time = UNIX_MILLIS(TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 2 HOUR)); SELECT * FROM `project.dataset.sales` FOR SYSTEM_TIME AS OF TIMESTAMP_MILLIS(snapshot_time)

4. FOR SYSTEM_TIME AS OF 構文(SQL標準)

-- SQL標準の構文でも指定可能 SELECT * FROM `project.dataset.sales` FOR SYSTEM_TIME AS OF TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR) WHERE region = 'APAC' -- 絶対時刻で指定 SELECT * FROM `project.dataset.sales` FOR SYSTEM_TIME AS OF TIMESTAMP('2024-12-05 10:30:00')

🔍 実用的なクエリ例

1. 誤って削除したデータの復元

-- 削除前のデータを確認(1時間前) SELECT * FROM `project.dataset.customers@-3600000` WHERE customer_id = 'CUST-12345' -- 削除されたデータを復元(INSERTで戻す) INSERT INTO `project.dataset.customers` SELECT * FROM `project.dataset.customers@-3600000` WHERE customer_id = 'CUST-12345' AND NOT EXISTS ( SELECT 1 FROM `project.dataset.customers` current WHERE current.customer_id = 'CUST-12345' )

2. データ変更の差分確認

-- 現在と1時間前のデータを比較 WITH current_data AS ( SELECT product_id, price, stock FROM `project.dataset.products` ), past_data AS ( SELECT product_id, price, stock FROM `project.dataset.products@-3600000` ) SELECT c.product_id, p.price AS old_price, c.price AS new_price, c.price - p.price AS price_change, p.stock AS old_stock, c.stock AS new_stock, c.stock - p.stock AS stock_change FROM current_data c LEFT JOIN past_data p USING (product_id) WHERE c.price != p.price OR c.stock != p.stock ORDER BY ABS(c.price - p.price) DESC

3. 削除されたレコードの特定

-- 昨日存在して今日削除されたレコードを探す SELECT old.*, 'DELETED' AS status FROM `project.dataset.orders@-86400000` old -- 24時間前 LEFT JOIN `project.dataset.orders` current ON old.order_id = current.order_id WHERE current.order_id IS NULL -- 現在のテーブルに存在しない

4. 新規追加されたレコードの特定

-- 過去1時間で追加されたレコード SELECT current.*, 'NEW' AS status FROM `project.dataset.orders` current LEFT JOIN `project.dataset.orders@-3600000` old ON current.order_id = old.order_id WHERE old.order_id IS NULL -- 1時間前には存在しなかった

5. データ監査(Audit Log)

-- 特定期間内のすべての変更を追跡 WITH snapshots AS ( -- 複数時点のスナップショットを取得 SELECT 'T-0' AS snapshot_time, * FROM `project.dataset.inventory` UNION ALL SELECT 'T-1h', * FROM `project.dataset.inventory@-3600000` UNION ALL SELECT 'T-2h', * FROM `project.dataset.inventory@-7200000` UNION ALL SELECT 'T-4h', * FROM `project.dataset.inventory@-14400000` ) SELECT snapshot_time, product_id, quantity, LAG(quantity) OVER (PARTITION BY product_id ORDER BY snapshot_time) AS previous_quantity, quantity - LAG(quantity) OVER (PARTITION BY product_id ORDER BY snapshot_time) AS change FROM snapshots WHERE product_id = 'PROD-123' ORDER BY snapshot_time, product_id

6. 集計値の時系列比較

-- 過去24時間の時間別売上推移 WITH hourly_snapshots AS ( SELECT 0 AS hours_ago, SUM(amount) AS total_sales FROM `project.dataset.sales` UNION ALL SELECT 4, SUM(amount) FROM `project.dataset.sales@-14400000` -- 4時間前 UNION ALL SELECT 8, SUM(amount) FROM `project.dataset.sales@-28800000` -- 8時間前 UNION ALL SELECT 12, SUM(amount) FROM `project.dataset.sales@-43200000` -- 12時間前 UNION ALL SELECT 24, SUM(amount) FROM `project.dataset.sales@-86400000` -- 24時間前 ) SELECT hours_ago, total_sales, total_sales - LAG(total_sales) OVER (ORDER BY hours_ago DESC) AS growth FROM hourly_snapshots ORDER BY hours_ago

🆚 関連機能との比較

スナップショットデコレータ
用途:
過去7日間の任意時点を参照
特徴:
• 無料(追加コストなし)
• 7日間の保持期間
• 読み取り専用
• 自動で有効
• 構文: @タイムスタンプ
最適なケース:
短期的なデータ復元、デバッグ、監査
テーブルスナップショット
用途:
長期バックアップ・復元
特徴:
• 有料(ストレージコスト)
• 最大7日間保持
• 明示的に作成が必要
• 復元可能
CREATE SNAPSHOT
最適なケース:
長期バックアップ、重要な時点の保存
Time Travel(一般)
概念:
過去のデータ状態にアクセスする機能全般
実装方法:
• スナップショットデコレータ
• テーブルスナップショット
• テーブルクローン
• Time Travelクエリ
保持期間:
• デフォルト: 7日間
• 変更不可
• 全テーブル共通

コスト:
• デコレータ: 無料
• スナップショット: 有料

⏱️ 保持期間と制限

Time Travelの保持期間

Time Travel保持期間
7日間(168時間)
過去7日間のデータにアクセス可能
📋 重要な制限事項
  • 保持期間: デフォルト7日間、変更不可
  • アクセス範囲: 過去7日以内のみ、それ以前は不可
  • 削除テーブル: 削除後7日間はアクセス可能
  • 読み取り専用: 過去データの変更・削除は不可
  • パーティション: パーティションテーブルも対応
操作 可否 備考
SELECT(読み取り) ✅ 可能 過去7日間のデータを参照可能
INSERT(挿入) ❌ 不可 過去データへの挿入は不可
UPDATE(更新) ❌ 不可 過去データの更新は不可
DELETE(削除) ❌ 不可 過去データの削除は不可
JOIN ✅ 可能 複数時点のデータを結合可能
集計関数 ✅ 可能 SUM、COUNT、AVG等すべて可能
CREATE TABLE AS ✅ 可能 過去データから新テーブル作成可

🎯 ユースケース

1️⃣ 誤削除からのデータ復元

シナリオ: DELETEクエリで誤って大量のレコードを削除

対応手順:
  1. 削除前の時点を特定(例: 30分前)
  2. スナップショットデコレータで削除されたデータを確認
  3. SELECT + INSERTで現在のテーブルに復元
  4. データ整合性を確認
メリット: 数分で復元完了、バックアップ不要

2️⃣ データ変更の監査・追跡

シナリオ: 重要なマスタデータの変更履歴を追跡

実装:
  • 定期的に複数時点のスナップショットをクエリ
  • 変更箇所を検出(価格変更、在庫変動等)
  • 変更履歴をログテーブルに保存
  • 異常な変更を検知してアラート
メリット: 監査ログの自動生成、コンプライアンス対応

3️⃣ ETL失敗時のリカバリ

シナリオ: ETLジョブが誤ったデータで上書き

対応:
  • ETL実行前の状態をスナップショットで確認
  • 正しいデータを抽出して新テーブルに保存
  • 誤ったデータを削除
  • 正しいデータで置き換え
メリット: 迅速なリカバリ、ダウンタイム最小化

4️⃣ A/Bテストの事前事後比較

シナリオ: 機能リリース前後のデータを比較分析

実装:
  • リリース直前のデータをスナップショット参照
  • リリース後のデータと比較
  • 主要メトリクスの変化を分析
  • 統計的有意性を検証
メリット: 正確な事前事後比較、影響度測定

5️⃣ デバッグとトラブルシューティング

シナリオ: 異常なデータが突然出現、原因調査が必要

調査方法:
  • 複数時点のスナップショットを比較
  • 異常データが最初に現れた時点を特定
  • その時間帯の処理を調査
  • 根本原因を特定して修正
メリット: 迅速な原因特定、時系列での変化追跡

💡 ベストプラクティス

項目 推奨事項
タイムスタンプ管理 重要な操作の前後でタイムスタンプをログに記録
復元前の確認 復元前に必ずスナップショットでデータを確認
定期的なバックアップ 7日以上保持したい場合はテーブルスナップショット使用
テスト環境での検証 本番復元前にテスト環境で手順を検証
権限管理 Time Travelアクセスにも適切な権限制御を設定
コスト管理 頻繁なスナップショット参照はクエリコストに含まれる
ドキュメント化 復元手順をランブックとして文書化
⚠️ 注意点:

✅ スナップショットデコレータの利点

📚 まとめ

🎓 スナップショットデコレータの重要ポイント

💡 使い分けガイド:
  • スナップショットデコレータ: 短期的なデータ参照・復元(7日以内)
  • テーブルスナップショット: 長期バックアップ(7日以上)
  • エクスポート: 永続的なバックアップ(無期限保存)
スナップショットデコレータで、
安全で迅速なデータ管理を実現しましょう!