0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

BigQuery の APPENDS と CHANGES の比較

0
Posted at

はじめに

BigQuery には、テーブルに追加された行の履歴を取得できる APPENDS 関数と、INSERTUPDATEDELETE などの変更履歴を取得できる CHANGES 関数があります。

どちらもテーブルの変更履歴を確認するための関数ですが、取得できる変更の種類や指定可能な期間などに違いがあります。

本記事では、同じテーブルに対して INSERTUPDATEDELETE を実行し、APPENDSCHANGES でどのような結果が取得できるのかを比較します。

特に、以下の点を確認します。

  • APPENDS ではどの変更が取得できるのか
  • CHANGES では INSERTUPDATEDELETE がどのように記録されるのか
  • テーブル作成時点から履歴を取得した場合の APPENDSCHANGES の違い
  • CHANGES に存在する「最大1日」の取得期間制限

サンプルテーブル作成

まず、動作確認に使用するテーブルを作成します。

今回は APPENDS だけでなく CHANGES の動作も確認するため、テーブル作成後に enable_change_history = TRUE を設定しています。APPENDS の利用だけであれば、enable_change_history の設定は必要ありません。

CREATE OR REPLACE TABLE
  `<PROJECT_ID>.<DATASET_ID>.<TABLE_NAME>`
(
  customer_id STRING,
  customer_name STRING,
  email STRING,
  phone_number STRING,
  postal_code STRING,
  address STRING,
  membership_rank STRING,
  signup_date DATE,
  is_active BOOL,
  created_at TIMESTAMP
);

ALTER TABLE `<PROJECT_ID>.<DATASET_ID>.<TABLE_NAME>`
SET OPTIONS (
  enable_change_history = TRUE
);

本記事では、テーブル作成時点からの履歴も確認するため、検証日の2日前に以下の初期データを登録しています。

初期データ
INSERT INTO
  `<PROJECT_ID>.<DATASET_ID>.<TABLE_NAME>`
(
  customer_id,
  customer_name,
  email,
  phone_number,
  postal_code,
  address,
  membership_rank,
  signup_date,
  is_active,
  created_at
)
VALUES
  (
    'C001',
    '山田 太郎',
    'taro.yamada@example.com',
    '090-1234-5678',
    '100-0001',
    '東京都千代田区千代田1-1',
    'GOLD',
    DATE '2024-01-15',
    TRUE,
    TIMESTAMP '2026-08-05 01:00:00+00'
  ),
  (
    'C002',
    '佐藤 花子',
    'hanako.sato@example.com',
    '080-2345-6789',
    '150-0001',
    '東京都渋谷区神宮前2-2',
    'SILVER',
    DATE '2024-03-20',
    TRUE,
    TIMESTAMP '2026-08-05 01:05:00+00'
  ),
  (
    'C003',
    '鈴木 一郎',
    'ichiro.suzuki@example.jp',
    '070-3456-7890',
    '530-0001',
    '大阪府大阪市北区梅田3-3',
    'STANDARD',
    DATE '2024-06-01',
    TRUE,
    TIMESTAMP '2026-08-05 01:10:00+00'
  ),
  (
    'C004',
    '高橋 美咲',
    'misaki.takahashi@example.com',
    NULL,
    '460-0001',
    '愛知県名古屋市中区三の丸4-4',
    'GOLD',
    DATE '2025-01-10',
    TRUE,
    TIMESTAMP '2026-08-05 01:15:00+00'
  ),
  (
    'C005',
    NULL,
    'anonymous@example.com',
    '09012345678',
    NULL,
    NULL,
    'STANDARD',
    DATE '2025-04-05',
    FALSE,
    TIMESTAMP '2026-08-05 01:20:00+00'
  ),
  (
    'C006',
    'John Smith',
    'john.smith+test@example.com',
    '+81-90-4567-8901',
    '060-0001',
    '北海道札幌市中央区北一条西5-5',
    'SILVER',
    DATE '2025-07-12',
    TRUE,
    TIMESTAMP '2026-08-05 01:25:00+00'
  );

DML を実行

続いて、APPENDSCHANGES の違いを確認するため、同じレコードに対して INSERTUPDATEDELETE の順に DML を実行します。

INSERT INTO `<PROJECT_ID>.<DATASET_ID>.<TABLE_NAME>`
VALUES
  (
    'C000',
    '山田 太郎',
    'taro.yamada@example.com',
    '090-1111-2222',
    '100-0001',
    '東京都千代田区千代田1-1',
    'GOLD',
    DATE '2026-08-01',
    TRUE,
    CURRENT_TIMESTAMP()
  );

UPDATE `<PROJECT_ID>.<DATASET_ID>.<TABLE_NAME>`
SET
  membership_rank = 'PLATINUM',
  email = 'new.taro.yamada@example.com'
WHERE customer_id = 'C000';

DELETE FROM `<PROJECT_ID>.<DATASET_ID>.<TABLE_NAME>`
WHERE customer_id = 'C000';

APPENDSCHANGES を確認

ここからは、先ほど実行した DML が APPENDSCHANGES でどのように取得されるのかを確認します。

まずは DML を実行する直前の時刻を start_timestamp に指定し、その時刻からクエリ実行時点までの変更履歴を取得します。

DML 実行直前から現在時刻まで

まず APPENDS を実行します。

end_timestampNULL を指定すると、クエリの実行開始時点までに追加された行が取得対象になります。

SELECT 
  customer_id,
  _CHANGE_TYPE,
  _CHANGE_TIMESTAMP
FROM APPENDS(
  TABLE `<PROJECT_ID>.<DATASET_ID>.<TABLE_NAME>`,
  TIMESTAMP '2026-08-07 04:20:00+00',
  NULL
)
ORDER BY _CHANGE_TIMESTAMP
;

実行結果を見ると、C000INSERT のみが取得されています。

その後に実行した UPDATEDELETEAPPENDS の履歴には追加されません。

image.png

続いて、同じ期間を指定して CHANGES を実行します。

SELECT 
  customer_id,
  _CHANGE_TYPE,
  _CHANGE_TIMESTAMP,
  _CHANGE_IS_FOR_UPDATE
FROM CHANGES(
  TABLE `<PROJECT_ID>.<DATASET_ID>.<TABLE_NAME>`,
  TIMESTAMP '2026-08-07 04:20:00+00',
  NULL
)
ORDER BY _CHANGE_TIMESTAMP
;

CHANGES では、INSERTUPDATEDELETE による変更を確認できます。

UPDATE が実行された場合、更新前のレコードは _CHANGE_TYPE = 'DELETE'、更新後のレコードは _CHANGE_TYPE = 'UPDATE' として出力されます。

image.png

テーブル作成時点から現在時刻まで

次に、start_timestampend_timestamp の両方に NULL を指定し、テーブル作成時点から現在までの履歴を取得してみます。

今回のテーブルは検証日の2日前に作成しており、テーブル作成時刻は BigQuery のタイムトラベル期間内にあります。

image.png

image.png

まず APPENDS を実行します。

SELECT 
  customer_id,
  _CHANGE_TYPE,
  _CHANGE_TIMESTAMP
FROM APPENDS(
  TABLE `<PROJECT_ID>.<DATASET_ID>.<TABLE_NAME>`,
  NULL,
  NULL
)
ORDER BY _CHANGE_TIMESTAMP
;

APPENDS では、テーブル作成時点から現在までに追加された行の履歴を取得できます。

image.png

同じ条件で CHANGES も実行してみます。

SELECT 
  customer_id,
  _CHANGE_TYPE,
  _CHANGE_TIMESTAMP,
  _CHANGE_IS_FOR_UPDATE
FROM CHANGES(
  TABLE `<PROJECT_ID>.<DATASET_ID>.<TABLE_NAME>`,
  NULL,
  NULL
)
ORDER BY _CHANGE_TIMESTAMP
;

こちらはエラーになります。

CHANGES では、start_timestampend_timestamp の間に指定できる期間が最大1日に制限されています。

今回はテーブル作成から2日以上経過しているため、start_timestamp = NULL によってテーブル作成時点から取得しようとすると、1日の上限を超えてエラーになります。

image.png

Updated change history start time to table creation time. The change history time window for CHANGES TVF exceeds the maximum allowed time window seconds of 86400. Start time: 2026-08-05T04:18:11.371Z, end time: 2026-08-07T05:15:08.866001Z. Table: 578497549185:<DATASET_ID>.<TABLE_NAME>

まとめ

APPENDSCHANGES の違いを整理すると、以下のようになります。

項目 APPENDS CHANGES
INSERT 取得できる 取得できる
UPDATE 取得できない 取得できる
DELETE 取得できない 取得できる
enable_change_history 不要 必要
1回に指定できる期間 1日の制限なし 最大1日
タイムトラベル期間の制限 あり あり
_CHANGE_IS_FOR_UPDATE なし あり
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?