Aurora DSQL が IDENTITY / SEQUENCE をサポート - 既存テーブルの移行方法も検証してみた
2026/2/13、Amazon Aurora DSQL で IDENTITY カラムと 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 はこれまで SERIAL や SEQUENCE をサポートしていませんでした。
「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倍と大きく、用途に応じた適切な値の選択が重要です。
採番のために外部の仕組みを用意していた方にとって、待望のアップデートではないでしょうか。実例として紹介した記事のタグ管理システムでも、移行に向けて着手したいと考えています。








