Edited at

データベースに画像を格納したいとき


画像 ( などの大容量メディアファイル ) を DB に格納したい

よくあるこの状況に関して、「SQLアンチパターン」第11章で述べられていたので、自分なりにまとめてみます。


ファイルパスを VARCHAR で格納するか、BLOB 型で格納するか

私が過去に開発に携わったサービスでは、画像はデータベースの外に保存し、ファイルパスをデータベースに格納していました。

しかし、画像のバイナリデータを BLOB 型でデータベースに格納するという方法もあります。

それぞれのメリットとデメリットを比べてみましょう。


ファイルパスを格納する場合のメリット


  • データベースの容量を減らせる

  • データベースのバックアップが短時間で終了し、バックアップファイル容量も小さくなる。

  • 画像のプレビューや編集が容易になる


ファイルパスを格納する場合のデメリット


  • データベース上で削除しても、ファイルパスの先のファイルは自動的には削除されない

  • トランザクションが分離するため、「ファイルはもうないのに該当する行を参照できる」という瞬間が生まれる

  • 行を削除しようとする操作をロールバックしたとき、先に画像を削除していた場合、画像だけが消えた状態になってしまう。

  • データベースのバックアップツールだけでは、画像ファイルのバックアップが行えない

  • SQL におけるアクセス権限 ( GRANT, REVOKE ) が画像ファイルにそのものに適用されない

  • データベースにはファイルパスが正当な値であるかどうかがわからない ( アプリケーションコード頼みになる )


BLOB 型に格納する場合のメリット


  • 誤ったファイルパスを格納するリスクがない

  • 行の削除と同時に画像も削除される

  • 画像の変更がコミットするまで他のクライアントには見えない

  • トランザクションをロールバックすると、画像を以前の状態に復元できる

  • 行の更新時はロックされるため、複数のクライアントが同時に画像を更新できない

  • データベースのバックアップにはすべての画像が含まれる

  • SQL におけるアクセス権限によって、行と画像へのアクセスを管理できる


BLOB 型に格納する場合のデメリット


  • 画像ファイルを BLOB列に読み込むための方法が必要 ( 一部データベース製品では外部ファイルをロードする関数を提供している )

  • ファイルパスと比べ、容量が大きくなる

  • ファイルパスと比べ、バックアップに時間がかかり、データベースのバックアップファイルが大きくなる