リモート開発メインのソフトウェア開発企業のエンジニアブログです

データベースの論理削除と物理削除

最近、開発をしていてユーザーログイン情報テーブルの削除方法について議論する機会があり、自分の思考を整理するために少しその議論の過程をまとめてみることにしました。

まず現状のシステムの状態から見ていきたいと思います。

方法1:論理削除のみ行う

現状はユーザーログイン情報テーブルに「削除ステータス」カラムを設けて、このステータスを変えることで論理削除を行い、レコード自体の物理削除は行わない様にしています。(他にカラムとして「メールアドレス」、「パスワード」があることを前提として話を進めます。)

削除ステータスには「通常ユーザー状態」と「休眠ユーザー状態」があり、サイト管理者がステータスを休眠に移行するとログインが出来なくなりますが、通常ユーザーにステータスを戻すという操作をすればアカウントも復活し、通常ユーザー時に書いていたブログもそのまま復活させることが出来ます。(サイト管理者がユーザの登録・管理をするタイプのシステムです。)

今回はユーザーログイン情報である「メールアドレス」、「パスワード」のうちのメールアドレスに関連する改修を実現するための議論について書いています。

具体的には上記の仕様のままだと物理削除がされていないため、休眠ユーザーに移行したアカウントのメールアドレスを再利用することが出来ないという問題を抱えています。メールアドレスは主キーになっているため重複させることが出来ないためです。

そこで以下のような仕様に変更することにしました。

方法2:論理削除の後、物理削除を行う

いきなり物理削除ができる様な仕様にしてしまうと、サイト管理者に「間違って消してしまったので戻して」と言われた場合に保守・運用側としては非常に面倒なことになるので、論理削除した後に少し時間を置いてから物理削除を行うような設計にしました。(もし削除したデータの復元を考えるなら方法1で書いたブログの復活の部分の仕組みも考える必要が出てきます。)

具体的には、「休眠ユーザー」に移行した後、1週間くらいしたら画面のリストの対象ユーザーに「物理削除」ボタンが現れて、ここで押せばデータベースから消え去るという仕組みにしました。いきなり削除ではなくワンクッション置いて、間違いなく削除して良いユーザーであることを確認してもらってから最後の削除を行うというコンセプトです。

今回はこのような仕組みにしましたが、理想は物理削除せずにメールアドレスの再利用が出来ることだと思います。それは以下のような設計で実現可能かもしれないのでパターンを書いておきます。

方法3:論理削除の後、メールアドレスをリネームする

画面の流れなどは方法2と同じで、「物理削除」ボタンを押した際にメールアドレスを以下のように変更することで対応して、実際の物理削除は行わないという仕様です。これであればアカウントの復元が割とし易い方なのではないかと考えています。

変更前:
test@example.com

変更後:
test@example.com.backup20201212090909

Railsのdeviseでこれができるかどうかについて時間があれば検証してみたいと思います。

方法4:レコードをバックアップしてから物理削除を行う

おそらく一番工数のかかる修正方法だと思います。物理削除する前に復元が必要なレコードをバックアップテーブルに全て移しておくというコンセプトです。

usersテーブル、blogsテーブルが元々あるテーブルなら、物理削除するアカウントに関連する情報をuser_backupsテーブル、blog_backupsテーブルに移しておくといった感じの設計になります。

方法5:AWS BackupでバックアップされたRDSからデータを復元するバッチを作る

削除の際、論理削除は考えずにいきなり物理削除のみの対応とします。アカウントが消された日を記録しておく仕掛けが必要な気がします。少し面倒な仕様になりそうですが実現は出来そうです。

まとめ

どの設計が優れているかという議論も有意義だとは思いますが、コストを余りかけられない場合もあると思いますので、サイト管理者と保守・運用側の双方が幸せになれる仕様に落とし込む必要があると感じる事案だったと思います。

他にも面白そうな修正方法があれば追記したいと思います。ではまた。

← 前の投稿

docker-compose.ymlのサービス名にアンダースコアを使うと正しいインターネットホスト名ではなくなる

次の投稿 →

Scalaのコレクションで遅延処理を行う

コメントを残す