概要
- ソフトデリート 設計の複雑さと落とし穴についての考察
- archived_atカラム 方式の問題点と運用上のリスク
- アーカイブ方法の代替案 (アプリイベント、トリガー、WALベースCDCなど)の紹介
- 各方式のトレードオフ と運用負担についての比較
- 新規プロジェクトへの推奨策 としてトリガー方式を提案
ソフトデリート設計の課題
- 多くのソフトウェアプロジェクトで ソフトデリート (deletedフラグやarchived_atカラム)を実装
- 顧客が誤ってデータを削除しても 復元が容易 になり、カスタマーサポートの負担軽減
- 監査やコンプライアンス 目的でアーカイブデータの保持が必要な場合も多い
- archived_atカラム方式は クエリや運用、アプリケーションコード に複雑さが波及
- 実際の復元は稀で 大半のアーカイブデータは読まれない ため、テーブルに大量の「死んだデータ」が蓄積
- アクセスパターンによっては データ量が膨大 になりうる
- APIやTerraformとの連携不備で 不要なレコード再作成が繰り返され、死んだ行が増大
- ストレージコストは安価 だが、アーカイブデータの扱いを放置しやすい
- バックアップ復元時 に死んだデータが障害となり、復元や再構築に時間がかかるリスク
archived_atカラム方式の運用上の問題
- クエリや運用作業の複雑化
- 常にアーカイブ済みデータを除外する必要
- インデックス設計の工夫が必要
- 手動クエリや分析時のクエリが冗長化
- アーカイブデータの誤混入リスク
- 関連テーブルやマッピングテーブル が絡むと複雑さが増大
- マイグレーション時 に古いアーカイブデータへの対応が難しい
- 復元処理 がAPIの通常作成処理と乖離しやすく、不具合の温床
- 標準API経由での復元に統一することで運用の簡素化が可能
代替案1:アプリケーションレベルのアーカイブ
- レコード削除時に アプリケーション層でイベント発行 (例:SQSへ送信、S3へアーカイブ)
- 主DBとアプリケーションコードが単純化
- 非同期処理で外部リソースのクリーンアップも容易
- JSON形式でデータを柔軟に保存可能
- トレードオフ:
- アプリケーションコードのバグ でアーカイブ漏れが発生しやすい
- インフラ構成が複雑化 (複数サービス・メッセージキューが必要)
- S3上のアーカイブ検索が困難 でカスタマーサポート用の追加ツールが必要
代替案2:トリガーによるアーカイブ
- 削除前にトリガーでアーカイブテーブルへコピー
- アーカイブテーブルは 汎用JSONカラム で設計可能
- サンプルテーブル・トリガー関数例
- archiveテーブル:id, table_name, record_id, data, archived_at, caused_by_table, caused_by_id
- トリガーで 削除元テーブル名やID、削除理由を記録
- 外部キーのカスケード削除対応
- セッション変数で 親子関係の削除理由 を伝播
- トレードオフ:
- 削除時のパフォーマンス低下 (トリガーの分だけオーバーヘッド)
- アーカイブテーブルの肥大化
- しかし、 本番テーブルはシンプルなまま運用可能
- アーカイブの削除やパーティション分割も容易
- クエリやインデックスの効率維持
- マイグレーションやバックアップも容易
代替案3:WALベースのChange Data Capture(CDC)
- PostgreSQLの WAL(Write-Ahead Log) を利用して変更履歴を外部システムへ転送
- 代表的なツール: Debezium (Kafka連携)、pgstream、wal2json、pg_recvlogical
- DELETEイベントのみ抽出し、外部ストレージへ保存
- トレードオフ:
- 運用負担が大きい (KafkaやDebeziumの監視・保守が必要)
- WAL蓄積によるディスク圧迫リスク
- max_slot_wal_keep_sizeで制御可能
- レプリケーションスロットの監視・アラートが必須
- スキーマ変更時の調整が難しい
- メリット:
- アプリケーションやDBスキーマを変更せずに運用可能
- 複数の出力先(S3, Elasticsearch等)に同時転送が可能
- 本番DBのクエリ負荷が増えない
代替案4:削除を適用しないレプリカ
- 削除クエリを適用しないPostgreSQLレプリカ のアイデア
- 過去データのクエリが容易
- 削除情報の追跡・分離やスキーマ移行時の整合性に課題
- 運用コストやストレージコスト も無視できない
結論と推奨策
- 新規プロジェクトで ソフトデリート が必要なら、 トリガー方式 が最適解
- 本番テーブルのクリーンさ
- 運用・クエリ・マイグレーションの容易さ
- 追加インフラ不要
- より複雑な要件や既存のKafka基盤がある場合は WALベースCDC も検討
- ご意見・ご質問はatlas9@eabuc.comまで