Aurora DSQL が IDENTITY / SEQUENCE をサポート - 既存テーブルの移行方法も検証してみた

Aurora DSQL が IDENTITY / SEQUENCE をサポート - 既存テーブルの移行方法も検証してみた

Amazon Aurora DSQL が待望の IDENTITY カラムと SEQUENCE をサポート!DynamoDB による外部採番が不要になり、DB側で完結するシンプルな構成が可能になりました。並列 INSERT のスループットを最大化する CACHE 設定の勘所と、既存テーブルからの移行手順も解説します。
2026.02.14

2026/2/13、Amazon Aurora DSQL で IDENTITY カラムと SEQUENCE オブジェクトのサポートが発表されました。

https://aws.amazon.com/jp/about-aws/whats-new/2026/02/amazon-aurora-dsql-adds-identity-columns-sequence/

DB側で整数IDの自動採番が可能になるアップデートです。開発中のシステムでちょうど代替実装をしていたので、実際のユースケースとあわせて紹介します。

アップデート概要

Aurora DSQL で以下が利用可能になりました。

  • GENERATED AS IDENTITY(IDENTITY カラム)
  • CREATE SEQUENCE / nextval()(シーケンスオブジェクト)

PostgreSQL 互換の標準SQL構文がそのまま使えます。Aurora DSQL が提供されている全リージョンで利用可能です。

ユースケース: AIタグ管理テーブルでの採番問題

テーブル構成

ブログ記事管理システムで、LLMが記事ごとにタグを自動生成する仕組みを開発中です。1記事に複数タグが紐づく(1:N)ため、タグテーブルには独立した主キー(サロゲートキー)が必要でした。

カラム名 説明
id BIGINT 主キー(自動採番)
post_id VARCHAR 記事ID
tag_id VARCHAR タグID(タグマスタと対応)
created_at TIMESTAMP 作成日時

なぜ採番が問題になるか

Aurora DSQL はこれまで SERIALSEQUENCE をサポートしていませんでした。

SELECT MAX(id) + 1 で採番する」方法はアンチパターンです。同時実行でID重複が発生し、レコード数の増加に伴い MAX(id) のスキャンコストも増大します。トランザクション分離レベルによっては不整合も起きえます。

これまでの対処: DynamoDB による採番管理

DynamoDB に採番管理テーブルを用意し、Atomic Counter(UpdateItem の ADD)で排他的にIDを発番していました。

DynamoDB を選んだのは、Atomic Counter による更新がアトミックでロックも確実なため、DSQL 側に負荷をかけずに安全に採番できるからです。

ただし、外部サービスへの依存が増え、採番→INSERT のトランザクション一貫性の担保が複雑になっていました。また、採番の排他制御のため、タグ付与処理の同時実行数を1に制限しており、並列処理ができず、大量の記事に対するタグ紐づけのスループットに課題を抱えていました。特に過去記事の一括タグ付けといった数万件規模の処理において、時間がかかる原因になっていました。

Before(DynamoDB 採番方式):

After(IDENTITY 方式):

DB側で採番が完結するため、採番テーブルが不要になります。並列実行が可能になり、Step Functions の Map 処理によるスループット改善や、同時実行数の制限も撤廃可能になります。

実機検証: IDENTITY カラムを試す

基本動作

テストテーブルを作成して自動採番、ID明示指定、バルクINSERTを確認しました。

DSQL 固有の制約として、CACHE サイズの明示指定が必須です。省略するとエラーになります(CACHE >= 65536 or = 1 を要求されます)。分散アーキテクチャにおいて、各コンピュートノードでシーケンス値をバッチ処理し、グローバルなロック競合を避けるための設計と考えられます。

Before(これまで): id の採番はアプリ側で管理

CREATE TABLE post_tag (
    id BIGINT NOT NULL PRIMARY KEY,
    post_id VARCHAR NOT NULL,
    tag_id VARCHAR NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- アプリ側で採番した id を指定して INSERT
INSERT INTO post_tag (id, post_id, tag_id)
VALUES (12345, 'post-001', 'aws');

After(IDENTITY): id はDB側で自動採番

CREATE TABLE post_tag (
    id BIGINT GENERATED BY DEFAULT AS IDENTITY (CACHE 65536) PRIMARY KEY,
    post_id VARCHAR NOT NULL,
    tag_id VARCHAR NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- id を省略するだけで自動採番
INSERT INTO post_tag (post_id, tag_id)
VALUES ('post-001', 'aws')
RETURNING id;

※ tag_id は別途タグマスタテーブルのキーと対応

IDENTITY カラムを定義する際、採番モードと CACHE サイズの指定が必要です。それぞれ確認しました。

GENERATED BY DEFAULT vs GENERATED ALWAYS

  • GENERATED BY DEFAULT — 自動採番だが、明示的にIDを指定することも可能。既存データの移行時に便利
  • GENERATED ALWAYS — 常にDB側で採番。ID指定はエラー
  • ALTER TABLE ... SET GENERATED ALWAYS / BY DEFAULT で既存テーブルの切り替えも可能

CACHE パフォーマンス比較

1000件のバルクINSERTで CACHE 1 と CACHE 65536 を比較しました。比較した結果が以下の通りです。

CACHE 1 CACHE 65536
所要時間 6.597秒 0.061秒
速度比 1x 約108x
ID連番性 完全連番 単一セッションでは連番(障害時にギャップあり)

なお、CACHE 65536 では各ノードが独立して異なる範囲の ID をキャッシュするため、IDは一意ですが、生成順と値の大小は一致しません。先に INSERT したレコードのほうが大きな ID を持つ逆転や、大きな欠番が生じることがあります。厳密な作成順でのソートが必要な場合は created_at を併用しましょう。

CACHE 1 は1件ごとにシーケンス値を永続化するため低速でした。
パフォーマンスが重視され、厳密な連番性を必要としないサロゲートキーのような用途では、CACHE 65536 の利用が推奨されます。大量のバルクINSERTを行う際は、このキャッシュ設定が処理時間に大きく影響するため、要件に合わせた慎重な検討が必要です。

既存テーブルへの後付け検証

ALTER TABLE は使えるか?

まず最もシンプルな方法を試しました。

ALTER TABLE post_tag
    ALTER COLUMN id ADD GENERATED BY DEFAULT AS IDENTITY (CACHE 65536);

結果は DSQL では未サポート でした。

ERROR: unsupported ALTER TABLE ALTER COLUMN ... ADD IDENTITY statement

標準 PostgreSQL では可能ですが、現時点の DSQL ではこの ALTER TABLE 構文に対応していませんでした。

新テーブル作成 → データ移植 → リネーム方式

ALTER TABLE が使えないので、新テーブルを作ってデータを移す方式で検証しました。

-- 1. IDENTITY 付き新テーブル作成
CREATE TABLE post_tag_new (
    id BIGINT GENERATED BY DEFAULT AS IDENTITY (CACHE 65536) PRIMARY KEY,
    post_id VARCHAR NOT NULL,
    tag_id VARCHAR NOT NULL,
    created_at TIMESTAMP
);

-- 2. 既存データを ID 保持で移植
INSERT INTO post_tag_new (id, post_id, tag_id, created_at)
SELECT id, post_id, tag_id, created_at
FROM post_tag;

-- 3. 開始値を設定
ALTER TABLE post_tag_new ALTER COLUMN id RESTART WITH <MAX(id) + 1>;

-- 4. テーブル入れ替え
ALTER TABLE post_tag RENAME TO post_tag_old;
ALTER TABLE post_tag_new RENAME TO post_tag;

検証結果

本番データ1000件で検証した結果です。

検証項目 結果
ALTER TABLE ... ADD IDENTITY ✗ DSQL 未サポート
IDENTITY 付き新テーブルへの ID 保持 INSERT
RESTART WITH で開始値設定
移植後の自動採番 ✓ 既存IDの続きから採番開始
ID 重複 なし ✓
RENAME TABLE ✓ サポート

GENERATED BY DEFAULT なので既存 ID を明示指定して INSERT でき、移植後は id 省略で自動採番に切り替わりました。テーブル入れ替えは RENAME で瞬時に完了しました。

まとめ

ALTER TABLE での後付けはできませんでしたが、新テーブル + リネーム方式で移行可能であることを確認しました。アプリ側の変更も、INSERT 文から id カラムを省略し、採番ロジックを削除するだけです。DynamoDB の採番テーブルと関連ロジックを完全に廃止でき、同時実行禁止の運用制約も解消されます。

CACHE 設定のパフォーマンス差は108倍と大きく、用途に応じた適切な値の選択が重要です。

採番のために外部の仕組みを用意していた方にとって、待望のアップデートではないでしょうか。実例として紹介した記事のタグ管理システムでも、移行に向けて着手したいと考えています。

参考リンク

この記事をシェアする

FacebookHatena blogX

関連記事