論理削除と物理削除 — 「消した」を、すべてのクエリが覚えていられるか
退会した会員にキャンペーンメールが届いた。論理削除は、削除を DB の操作から、すべてのクエリが守る約束に変える。
先に読んでおくとよい記事
この記事の進み方
What — 行を消すか、印を付けるか
削除には2つのやり方があります。
- 物理削除 —
DELETEで行そのものを消す。テーブルから無くなる - 論理削除 — 行は残し、「削除済み」の印(
deleted_atやis_deleted)を付ける。読むときに印の付いた行を除く
一見、論理削除は「消さないだけ」の安全な選択に見えます。ところが、「削除」という事実の置き場所が変わっています。
消したことを DB が保証する
DELETE FROM members WHERE id = 42- 消えたことを守る人
- DB
- 読むときの条件
- 要らない
- 復元
- バックアップからしかできない
- 一意制約・外部キー
- そのまま正しく効く
- –消した行は、どのクエリからも見えない。書き忘れという事故が起きない
- –外部キーが参照していれば、消す時点で DB が止めるか、連動させる
- –「いつ、誰が消したか」は残らない。必要なら別に記録する
違いは「消えるかどうか」ではなく、「消えたことを誰が守っているか」。物理削除では DB が守り、論理削除ではすべてのクエリが守る。
- 物理削除
- DELETE で行そのものを消すこと。ハードデリートとも呼ぶ。
- 論理削除
- 行を残したまま、削除済みの印を付けること。ソフトデリートとも呼ぶ。
- 一意制約
- 列の値がテーブル内で重複しないことを DB が保証する制約。
- 部分インデックス
- 条件を満たす行だけを対象にするインデックス。使える DB と使えない DB がある。
会員テーブルを論理削除にしています。退会した人が同じメールアドレスで再登録しようとすると「登録済み」で弾かれます。原因はどれですか?
Why — なぜ事故になるのか
物理削除では、「その行はもう無い」という事実を DB が守っています。消えた行はどの SELECT にも出てきません。書き忘れようがありません。
論理削除にすると、この事実は DB の外に出ます。「deleted_at が入っている行は無いものとして扱う」という約束に変わり、その約束を守るのは、テーブルを読むすべてのクエリです。
物理削除: DB が「無い」を保証する → 読む側は何も知らなくてよい
論理削除: 読む側が「無い」を再現する → 読む側全員が約束を知っている必要がある
アプリのコードだけなら、レビューや共通の関数で守れるかもしれません。ところがテーブルを読むのはアプリだけではありません。配信ツール、分析基盤、管理画面、障害対応で誰かが手で書く SQL。 その全員が約束を知っていることは、誰も保証していません。
制約も、削除を知らない
冒頭のもう1つの事故、再登録できない問題も同じ根から来ています。
一意制約も外部キーも、DB の上の「行」について約束するものです。deleted_at は、DB から見ればただの列の1つにすぎません。
- 一意制約 は、削除済みの行も数える。再登録が弾かれる
- 外部キー は、削除済みの親を「存在する」と見なす。退会した会員の注文も、参照先が有効なまま残る
- インデックス は、削除済みの行も含めて大きくなる。削除済みが9割のテーブルでも、索引は10割ぶん
「消した」と言える状態か
論理削除した行には、氏名もメールアドレスも住所も残っています。アプリの画面から見えないことと、消えていることは別です。
個人情報保護法には、利用する必要がなくなった個人データを遅滞なく消去するよう努める、という規定があります。「退会したので消しました」と利用者に説明するなら、少なくとも個人を特定できる情報は、実際に消えているか、特定できない形に置き換わっている必要があります。
論理削除を選ぶとき、ここが最も見落とされます。「戻せるから安全」は、運営者にとっての安全で、利用者にとっての安全ではありません。
会員を論理削除しました。その会員に紐づく注文は注文テーブルに残っています。外部キー制約はこの状態をどう扱いますか?
演習 — まず自分で判断する
解説を読む前に、まず自分で判断してみてください。ここで一度詰まっておくと、 次の節の判断軸が「なるほど」ではなく「そう来たか」に変わります。
会員の退会を、どう実装しますか?
- 退会から30日間は、問い合わせがあれば復帰できるようにしたい
- 注文の記録は、会計上7年残す必要がある
- 会員テーブルは、アプリのほかに配信ツール・分析基盤・CS の管理画面が読む(別チームを含む)
- 退会した人の氏名・メールアドレス・住所は、不要になったら消したい
- 退会した人が、同じメールアドレスで再登録できる
- · 「削除」という言葉に、いくつの要求が混ざっているか
- · アプリの外から読まれたとき、退会者がどう見えるか
- · 注文を残すことと、個人情報を消すことを両立できるか
「全部論理削除にしておけば、間違えて消しても戻せるから安全」と言う同僚に、何が安全で何が危ないのかを説明してください
- 相手は論理削除を何度も使ってきた経験がある
- 過去に物理削除で本番データを消して、バックアップから戻した経験がある
- 頭ごなしに否定されると聞き入れにくい
読み終わりましたか?
読了にすると、これを前提とする記事がロードマップで開放されます。