画像 ( などの大容量メディアファイル ) を DB に格納したい
よくあるこの状況に関して、「SQLアンチパターン」第11章で述べられていたので、自分なりにまとめてみます。
ファイルパスを VARCHAR で格納するか、BLOB 型で格納するか
私が過去に開発に携わったサービスでは、画像はデータベースの外に保存し、ファイルパスをデータベースに格納していました。
しかし、画像のバイナリデータを BLOB 型でデータベースに格納するという方法もあります。
それぞれのメリットとデメリットを比べてみましょう。
ファイルパスを格納する場合のメリット
- データベースの容量を減らせる
- データベースのバックアップが短時間で終了し、バックアップファイル容量も小さくなる。
- 画像のプレビューや編集が容易になる
ファイルパスを格納する場合のデメリット
- データベース上で削除しても、ファイルパスの先のファイルは自動的には削除されない
- トランザクションが分離するため、「ファイルはもうないのに該当する行を参照できる」という瞬間が生まれる
- 行を削除しようとする操作をロールバックしたとき、先に画像を削除していた場合、画像だけが消えた状態になってしまう。
- データベースのバックアップツールだけでは、画像ファイルのバックアップが行えない
- SQL におけるアクセス権限 ( GRANT, REVOKE ) が画像ファイルにそのものに適用されない
- データベースにはファイルパスが正当な値であるかどうかがわからない ( アプリケーションコード頼みになる )
BLOB 型に格納する場合のメリット
- 誤ったファイルパスを格納するリスクがない
- 行の削除と同時に画像も削除される
- 画像の変更がコミットするまで他のクライアントには見えない
- トランザクションをロールバックすると、画像を以前の状態に復元できる
- 行の更新時はロックされるため、複数のクライアントが同時に画像を更新できない
- データベースのバックアップにはすべての画像が含まれる
- SQL におけるアクセス権限によって、行と画像へのアクセスを管理できる
BLOB 型に格納する場合のデメリット
- 画像ファイルを BLOB列に読み込むための方法が必要 ( 一部データベース製品では外部ファイルをロードする関数を提供している )
- ファイルパスと比べ、容量が大きくなる
- ファイルパスと比べ、バックアップに時間がかかり、データベースのバックアップファイルが大きくなる