Darumaotoshi: 論理削除ではない復旧可能な削除
基盤ユニットの小山です( @k1LoW )。
会社の技術ブログは敷居が高いので、チームの非公式技術ブログをはじめることになりました。
よろしくおねがいします。
今回は、CakePHP3での削除プラグインDarumaotoshiの紹介をします。
論理削除と設計
データベース設計におけるいわゆる論理削除については、論理削除 Casual Talksというイベントがあるほど様々な議論があります。
皆さんが言われていることについては大きく頷くばかりで、「設計しっかり」というのが大前提です。
削除してしまったものを簡単に復旧したい(かもしれない)機能
ここからスコープの小さい話をします。
単純に削除機能があるアプリケーションを作ったとき、「削除データを記録しておきたい」「削除してしまったものを簡単に復旧したい(かもしれない)」という要求があった場合、論理削除はひとつの選択肢となると思います。
多くのフレームワークで論理削除プラグインが作られていますし、CakePHPでも、UseMuffin/Trash やfusic/Reincarnationなど、いくつか存在します。
ただ、「削除データを記録しておきたい」「削除してしまったものを簡単に復旧したい(かもしれない)」という要求のためだけだと、 SELECTするときに常にWHERE句が追加で必要になるので、論理削除はあまり良い手段とは言えません。
実際はWHERE句の追加も論理削除プラグインがコード上隠蔽するのですが、それでも、いざフレームワークのORマッパーから外れてSQLを書くときにツラいです。
ただ、論理削除プラグイン以外の削除プラグインというのが、なかなかないというのも現状です。 (なぜなんですかね?)
というわけで、削除レコードをアーカイブ用のテーブルに退避させる方法をとったCakePHP3用の削除プラグインを作ってみました。
Darumaotoshi
Darumaotoshiは削除時に削除レコードを自動でアーカイブ化するプラグインです。
具体的には、アーカイブ用テーブル trash
を作っておいて、CakePHPのbeforeDeleteイベント発火時に、 trash
テーブルに削除レコードをアーカイブさせる形で削除レコードの情報を保持します。
<?php // in the initialize() method $this->addBehavior('Darumaotoshi.Darumaotoshi');
というふうにビヘイビアを有効にしてもらえれば、deleteメソッド発行時に自動でアーカイブ化も実行されます。
元のテーブルからはレコードは削除されているので、SELECTのWHERE句に影響もありません。
また、復旧するためのメソッドとして restore()
を提供しているので、それを利用して削除したレコードを元に戻すことも可能です。
現在は trash
テーブルに、シリアライズ化(JSON化)した削除レコードを雑にアーカイブ化するだけですが、同じスキーマの削除レコードテーブルへのアーカイブ化にも対応しようと思っています。
まとめ
CakePHP3用の削除プラグインDarumaotoshiを紹介しました。
データベース設計はしっかりしていきたいと思いました。
ちなみになぜ Darumaotoshi なのかというと、削除レコードを退避する様がだるま落としのイメージと似ていたからです。