今回は、RDBのテーブル設計においてよく見る「論理削除」について色々とネットや書籍なりで調べたものを自分なりにまとめておこうと思い、記事にしました。
論理削除とは?
まずは簡単に論理削除という言葉の定義から確認します。
論理削除とは、DELETE文によりテーブルからデータを物理的に削除するのではなく、論理的に削除することを指します。
例えば、以下の会員テーブルを例にして論理削除をみてみましょう。
■会員テーブル
id | 名前 | 削除フラグ |
---|---|---|
1 | 田中 | 0 |
2 | 佐藤 | 0 |
3 | 鈴木 | 1 |
4 | 吉田 | 0 |
このテーブルには削除フラグと呼ばれるカラムがあります。このカラムの値が"1"であれば削除済、"0"であれば未削除を表すというルールを作ります。上記の例であれば、id=3の鈴木さんは削除済みとなり、他の会員は未削除という状態です。
上記のようなルールの場合には、ある会員を削除したいとなった場合にはこの削除フラグを"1"(削除済)に更新することで論理的に削除した状態を表現します。これが論理削除と呼ばれるものです。
論理削除のメリット
よく言われる論理削除のメリットは以下になると思います。
- ユーザーからは削除されたように見せるが、実際にはデータ自体は念のため残しておきたいといった要件を満たせる
- 削除した後に、すぐに戻せる(あくまで論理的に削除しただけなので、削除フラグを更新することで簡単に元に戻せる)
論理削除のデメリット
反対によく言われる論理削除のデメリットは以下になると思います。
- データ抽出のSQLクエリに削除フラグの条件が毎回必要になる
- 論理削除すると、データがテーブルに残るのでディスクを圧迫する
- 論理削除のカラムはカーディナリティが低いので、パフォーマンスが悪い
考察
上記の通り、メリットとデメリットどちらも見てきました。
結局のところ、論理削除は使って良いのかというところですが、これは他でもよく言われていることですが、積極的に使うものではないと思います。
個人的にはデメリットの「データ抽出のSQLクエリに削除フラグの条件が毎回必要になる」がとてもやっかいだと思いました。
抽出条件に必ず削除フラグを付与しなくてはならないのは、かなり面倒ですしパフォーマンスも悪いとなるとやはり色々と問題を抱えていると思います。
それで、論理削除を使わない場合はどうするのかというと、対処法としては削除するデータは別テーブルに移動することが良いと言われています。
例えば、削除済会員テーブルを別途用意して会員テーブルから物理削除したデータを削除済会員テーブルに登録するということです。
そうすることで、元の会員テーブルから削除フラグをなくせて、抽出条件もきれいになるので良いですね。
また、すでに論理削除を運用している場合にはViewを上手く使うことでSQLクエリの抽出条件をシンプルにすることはできます。
ただし、これはあくまでも見かけ上の解決手段となりパフォーマンスをよくすることはできません。
まとめ
論理削除はすでに色々と議論されている話題ですが、その内容を自分なりに理解しながら整理することでより理解を深めることができました。
実際のところ、論理削除を絶対使ってはダメ!!ということではなく、そのメリデメをちゃんと理解して使う分には問題ないというところみたいです(これは多くのことにいえることですが)。
確かに論理削除フラグ便利ですよね。私が今まで見てきた現場でも必ずといって良いほど論理削除フラグを使っていたのですが、あれは場合によってはちょっとまずい設計だったのかなと改めて考えさせられました。
今回も最後までお読みいただきありがとうございました。この辺で失礼いたします。
参考
今回の論理削除について考えるにあたり、以下の資料を参考にさせていただきました。どれもとてもよく考察されていて、なるほどと思うところがたくさんありましたので未読の方は読まれるといいかと思います。PostgreSQLとMySQLで説明している資料もありますが、多くの部分が個々のDBMSによらない内容ですので参考になると思います。
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」 | PPT
MySQLで論理削除と正しく付き合う方法 | PPT
PostgreSQLアンチパターン | PPT