DBにおけるデータ削除の考え方

はじめに

システム開発をしていると、「DB内のデータを削除したい」という要件が出てくることがあります。
しかし、一言で削除と言っても、DBにおいては「物理削除」「論理削除」の2種類の方法があり、さらに、RDB(MySQL・PostgreSQLなど)とDynamoDBでは考え方も少し異なるため混乱しがちです。
今回は、それぞれの特徴と使い分けについてまとめます。

物理削除

物理削除とは、その名の通りデータをDBから完全に削除することです。削除後は、そのデータは残りません。
ストレージ容量を節約できる、検索対象が減ることでパフォーマンスを維持しやすい、というメリットがある反面、データを完全に削除するため仮に誤って消した時の復元が極めて困難になる、というデメリットもあります。

論理削除

論理削除とは、実際にはデータを削除せず、

deleted = true

deleted_at = 2026-07-24

などのフラグを付ける方法です。
例えば

idnamedeleted_at
1田中null
2佐藤2026-07-24

というレコードが保存されている時、

WHERE deleted_at IS NULL

と言った条件式を付けることで、削除済みデータを除外して検索することができます。

仮に誤って消した時の復元が容易である、他テーブルとの整合性を保ちやすい、という点がメリットとして挙げられ、実データが残り続けるためストレージ容量の圧迫につながりやすい、というデメリットがあります。

RDBにおけるデータ削除

RDBにおいては、外部キーやJOINを用いたテーブル同士の連携が重要となります。
例えば

users
 ↓
posts
 ↓
comments

のような関係では、親データ(users)を物理削除すると子データとの整合性が崩れます。
そのため、削除する際はdeletedやdeleted_atといったフラグを持たせる論理削除が一般的となります。

DynamoDBにおけるデータ削除

DynamoDBでもフラグとなるカラムを持たせての論理削除は可能です。
ただし、DynamoDBは外部キーやJOINという概念が存在せず、必要なデータは最初から一緒に持つ設計(デノーマライズ)が基本です。
そのため、親データを物理削除した時も子データとの整合性が崩れることがRDBと比べると少ない傾向にあります。

また、DynamoDBでは読み込んだデータ量に応じて料金が発生します。
例えば全データ100万件中90万件が論理削除済みだった場合、検索時には削除済みデータも読み込んだ上で除外するケースがあります。
その場合、結果として読み込みコスト増加、レスポンス悪化につながります。

以上の観点から、DynamoDBでは物理削除の方が相性がいいと言えます。

また、DynamoDBにはTTL(Time To Live)という機能があります。
例えば

deleted_at

とは別に

expire_at

といったカラムを設定すると、設定した日付を超えた場合に自動で物理削除されます。
例として


退会

30日保持

TTLで自動削除

という運用もできます。

どちらを選ぶべきか

一概に「物理削除が良い」「論理削除が良い」とは言えません。選択する時は、以下のような観点を重視するとよいでしょう。

物理削除が向いているケース

  • 一時データ
  • キャッシュ
  • ログ
  • セッション情報
  • 復元不要なデータ
  • データ量が非常に多い

論理削除が向いているケース

  • ユーザー情報
  • 投稿
  • 注文履歴
  • 契約情報
  • 復元の可能性があるデータ
  • 監査・履歴が必要なデータ

まとめ

データ削除はシステムの運用や将来の保守性に大きく関わる設計要素です。
一般的に、RDBでは外部キーやJOINとの整合性を保つため、論理削除が採用されるケースが多いです。一方DynamoDBでは、シンプルなアクセスパターンとコスト効率を重視し、物理削除を基本としつつ、必要に応じて論理削除やTTLを組み合わせる設計がよく採られます。

重要なのは、「どちらが優れているか」ではなく、データの性質やシステム要件に応じて適切な削除方法を選択することです。削除後の復元の必要性、履歴保持、参照整合性、ストレージコスト、検索性能などを総合的に考慮し、最適な設計を選ぶことが重要です。