論理削除を実装するにあたっての懸念点(Rails、paranoia)

f:id:ryoutaku_jo:20190701204855p:plain

【目次】

【本題】

論理削除の実装中に感じた懸念

業務で開発しているアプリケーションの、Userモデルに論理削除機能の実装を進めているが、この実装によってパフォーマンスや拡張性に悪影響を与えてしまうことを懸念している。

今回はそれについてまとめる。

なお、論理削除や、Railsで論理削除を実装する際に使用されるparanoiaについては、以前のブログを参照。

ryoutaku-jo.hatenablog.com

ryoutaku-jo.hatenablog.com

前提:paranoiaによる論理削除の実装方法

まず前提として、論理削除はgemのparanoiaを利用している。

paranoiaで論理削除を行う場合は、以下の作業を行う必要がある。

・論理削除を適用したいモデルにacts_as_paranoidを記述

・論理削除を適用したいテーブルにdelete_atカラムを追加する

また、現状Userモデルは、Active Recordのアソシエーション機能のオプションであるdependent: :destroyによって、レコード削除時に関連付けされたモデル(子モデル・孫モデル)のレコードも、同時に削除されるようにしている。

この同時削除されるレコードにも、論理削除を適用させたい場合は、先ほどのparanoiaを適用させる作業を、関連付けされたモデルでも行う必要があった(検証済み)

懸念1:パフォーマンスに影響を及ぼさないか?

私がSQL関連の知識に乏しいので、全く見当違いな心配をしているだけかもしれないが、論理削除の実装によってクエリの実行速度が全体的に低下することを懸念している。

paranoiaを適用させたモデルでは、すべてのクエリにdeleted_atを持たないレコードのみを含める様にスコープを設定することで、削除済みのデータが検索されない仕組みになっている。

つまり、全てのクエリにWHEREdeleted_at``が入ってしまうデメリットがある。

deleted_atにindexは貼っているものの、これによってクエリの実行速度が低下しないか懸念している。

また、Userモデルとdependent: :destroyのオプションで関連付けしているモデルは、孫モデルも含めれば「23個」存在する。

適用する必要がないモデル(Tokenモデルなど)も存在するが、User復元時にデータが無いと整合性が保て無くなるテーブルについては、delete_atカラムを追加する必要がある。

なので、このクエリ実行速度の低下は、Userモデル以外にも波及する恐れがある。

さらに、論理削除ではデータが残り続けるので、コメントを頻繁に作成/削除を繰り返された場合など、不要なデータが残り続けて、パフォーマンスに悪影響を与える可能性がある。

paranoia以外の実装方法を選択したとしても、論理削除であれば、削除状態を管理するためのカラムを持たせる必要が出るはずなので、結局同じ問題にぶつかると考えている。

現状思いつく解決策は以下の2つ。

・論理削除では無く、物理削除で対応する(別テーブルにユーザー情報を残す等)  →(問題点)関連モデルのデータは、どう保持するか?

dependent: :destroyで同時削除するモデルを絞る  →(問題点)ユーザーが消えているにも関わらず、そのユーザーに紐づいたデータが残り続けるのは、データの整合性に問題が生じないか?

懸念2:今後の拡張/保守に影響が出ないか?

Userモデルとdependent: :destroyのオプションで関連付けしているモデルは、基本的にparanoiaを適用させる必要がある。 今後、機能追加する中で、テーブルが増えた際に、paranoiaの適用が漏れてしまうと、データの整合性が取れなくなり、バグの温床となる懸念がある。

Userモデルと直接関連付けさせる場合には忘れにくいだろうが、Userモデル以外のUserモデルと間接的に関連付ける場合は、適用が漏れてしまう可能性がある。

私が思いつく解決策は以下。

・全てのテーブルににparanoiaを適用させる(全て論理削除)  →(問題点)不要なデータが残り続けて、パフォーマンスに悪影響を与えないか?

結論出ずじまい

結局色々調べるが、この問題に対する結論は出ず・・・

改めてSQL周りの知見が足りんと反省・・・

先輩に相談しながら、解決手段を探っていく!

《今日の学習進捗(3年以内に10000時間に向けて)》

AWSのエラーアラートに気づくのが遅れてしまった・・・(先輩に教えてもらうまで気づかないという失態・・・)

スマホの通知設定を変更して、直ぐに気づけるように対応したい。

学習開始からの期間 :206日
今日までの合計時間:1997h
一日あたりの平均学習時間:9.7h
今日までに到達すべき目標時間:1881h
目標との解離:116h
「10,000時間」まで、

残り・・・「8003時間!」