SQLアンチパターン-11章 幻のファイル-まとめ


画像はどうやって保存するべきなのか考えよう

自分自身、どの程度扱われているのかは分かりませんが
画像というものは、往々にして、あるサーバー上に画像ファイルとして保存されていると思います。
それはAWSのS3であったり、単純にアプリケーションサーバー上にあったりすると思います。

しかし、そもそも画像はデータなので、バイナリデータとして表すことも可能です。
そしてその値はDBに保存することが可能ですね。

よく使われる(であろう)ケース

画像をどこかのサーバー上に置いて保存する場合、
DBにはどのような情報が入るでしょうか。

image_id alt src
1 猫の画像 https://example.com/hogehoge_1.jpg
2 犬の画像 https://example.com/hogehoge_2.jpg
3 ペンギンの画像 https://example.com/hogehoge_3.jpg

このようなテーブルが用意できると思います。
画像のソースはsrcで表されますね。

デメリット

このパターンで運用する場合、どのようなデメリットがあるでしょうか。

ファイルを削除した時は?

ファイルを削除する際は、まずDBから該当の行を削除することになると思います。
しかし、ファイルそのものが削除される訳ではありません。
該当のファイルが削除されるようなプログラムを自前で作成する必要がありますね。

また、該当の行を削除するタイミングと、ファイル自体を削除するタイミングの間で、データの齟齬が起きる可能性もあります。

ロールバックをした時はどうなるのか

ファイルを削除する処理があったとします。
画像ファイルを削除した後に、該当行をDBから削除しようとして、ロールバックが起きた場合はどうなるでしょう。
DBの該当行は残ったとしても、画像ファイルは削除されたままです。
そのような問題を解決するための自前の処理を作成する必要がありますね・・・。

バックアップはどうなるのか

DBのバックアップと、画像ファイルのバックアップを同時に行えるようなツールってあるんですかね・・・。
特に優れたツールがない限りは、DBのバックアップと画像ファイルのバックアップは別軸の作業として発生すると思います。

データへのアクセス権限

DB上でのアクセス権限と、画像ファイル自体へのアクセス権限は別々で設定する必要があります。

ファイルの整合性

あくまでDB上の保存されているデータは画像ファイルのパスであり、
そのパスを叩くことで画像ファイルが存在しているかどうかを保証はしていません。
アプリケーション側で、画像ファイルが存在しているかどうか確認する処理が必要になります。

このアンチパターンを利用しても良いケース

扱う画像があまりにも多く、DBに負担がかかるほどであれば、外部のサーバーなどに画像ファイルを保存して置くのが良いでしょう。

DB上で画像ファイルを保存するメリット

  • 行の削除 = 画像削除になります。更新も同様で、値の整合性が保たれます。
  • ロールバックも整合性を保って行われます。
  • バックアップが一回の処理で済みます。
  • 権限管理もDB上だけで不備なく行えます。

まとめ

大体のwebサービスはこのアンチパターンを利用することにはなるのだと思います。
しかし、考えとして画像をBLOB型でDB上に保存するという手法も設計をする際には常に選択肢として残しておくべきでしょう。デファクトスタンダードに無意識に流されるのではなく、いつでも自分の持っている情報で判断をして、意思決定をしましょう。