両者のメリット・デメリットと通常のウェブアプリで、ファイルアップロード系保存の定石などあればお教えください。
画像などのファイルは、不特定多数に見られるプロフィール画像や、特定のコミュニティの人などしか見られない画像などアクセス制限が必要だったりなかったりしますが、アクセス数は大きくないとします。
どちらでも実装可能ですが、メリット・デメリットや一般的にはどうしているかが知りたいです。
これはサービスの規模にもよりますが、普通に小規模のシステムを構築するなら、DBに保存するのはファイルのパス(ファイルサーバの名前とパス)にとどめたほうがよいと思います。
最大の理由は、DBエンジン内のパフォーマンスです。DBを使うときに一番いいのは、DBの検索対象データを全部DBサーバのDRAM上に乗っけてしまうことです。ところが画像のように大きなデータだと全部をDRAM上に乗せられないので、いちいちHDDに探しに行くことになり、DBのパフォーマンスがHDDのランダムアクセス速度に縛られることになって著しく性能悪化します。DBの基本としては頻繁にアクセスされるデータのみ(ユーザIDとメールだけなど)を小さなテーブルに抜き出して、そのテーブルのデータだけは常にDRAM上に乗っかるサイズにデータ設計するのがDBパフォーマンスを落とさないこつです。
また、通常ウェブサーバとDBサーバは、socketでデータをやりとりします。通信しているわけですね。インターネット上のサーバとPCが通信しているのと原理的にはほとんど同じです。このため、検索結果としてのデータ(この場合はたとえば画像)を受け渡ししているとき、socketが一つ占有されています。画像のように大きなデータだと転送にも時間が掛かるので、socketの占有時間も長くなります。このため、アクセスが集中すると簡単にsocketを使い尽くしてwebサーバ~DBサーバ間の接続が失敗するようになります。
逆に、DBに画像データ本体をあえて格納するメリットとしては、検索や画像取り出しのインターフェースが統一できるので、いろんなメタデータをごちゃまぜにして取り扱ったり、多数のサーバや物理的に離れた遠隔地のサーバに分散して格納されているようなときでしょう。ファイルアクセスを「socket化」して隠蔽することによりシステムが抽象化してメンテや拡張がしやすくなります。
また、実例としては、mixiやはてなではファイルサーバのインターフェースにlighttpdなどのHTTPサーバを立てて、HTTPでデータをwwwサーバに渡す、ということをしているようです。これもあくまでDBのレコードにINSERTしているのはファイルとファイルサーバの位置情報だけであって、ファイル本体をBINARYでINSERT/SELECTしているわけではないと思います。
はてなの例はこちらの本に詳しく書いてありました。
[24時間365日] サーバ/インフラを支える技術 ‾スケーラビリティ、ハイパフォーマンス、省力運用 (WEB+DB PRESS plusシリーズ)
これはサービスの規模にもよりますが、普通に小規模のシステムを構築するなら、DBに保存するのはファイルのパス(ファイルサーバの名前とパス)にとどめたほうがよいと思います。
最大の理由は、DBエンジン内のパフォーマンスです。DBを使うときに一番いいのは、DBの検索対象データを全部DBサーバのDRAM上に乗っけてしまうことです。ところが画像のように大きなデータだと全部をDRAM上に乗せられないので、いちいちHDDに探しに行くことになり、DBのパフォーマンスがHDDのランダムアクセス速度に縛られることになって著しく性能悪化します。DBの基本としては頻繁にアクセスされるデータのみ(ユーザIDとメールだけなど)を小さなテーブルに抜き出して、そのテーブルのデータだけは常にDRAM上に乗っかるサイズにデータ設計するのがDBパフォーマンスを落とさないこつです。
また、通常ウェブサーバとDBサーバは、socketでデータをやりとりします。通信しているわけですね。インターネット上のサーバとPCが通信しているのと原理的にはほとんど同じです。このため、検索結果としてのデータ(この場合はたとえば画像)を受け渡ししているとき、socketが一つ占有されています。画像のように大きなデータだと転送にも時間が掛かるので、socketの占有時間も長くなります。このため、アクセスが集中すると簡単にsocketを使い尽くしてwebサーバ~DBサーバ間の接続が失敗するようになります。
逆に、DBに画像データ本体をあえて格納するメリットとしては、検索や画像取り出しのインターフェースが統一できるので、いろんなメタデータをごちゃまぜにして取り扱ったり、多数のサーバや物理的に離れた遠隔地のサーバに分散して格納されているようなときでしょう。ファイルアクセスを「socket化」して隠蔽することによりシステムが抽象化してメンテや拡張がしやすくなります。
また、実例としては、mixiやはてなではファイルサーバのインターフェースにlighttpdなどのHTTPサーバを立てて、HTTPでデータをwwwサーバに渡す、ということをしているようです。これもあくまでDBのレコードにINSERTしているのはファイルとファイルサーバの位置情報だけであって、ファイル本体をBINARYでINSERT/SELECTしているわけではないと思います。
はてなの例はこちらの本に詳しく書いてありました。
[24時間365日] サーバ/インフラを支える技術 ‾スケーラビリティ、ハイパフォーマンス、省力運用 (WEB+DB PRESS plusシリーズ)
なるほど、大変勉強になりました。
少し違うかもしれませんが、ユーザーからたとえばウイルスが送信されたとして、そのウイルスはunix上のシステムシステムを破壊するものだとすると、DB保存していれば大丈夫ですが、ファイル保存だと危ないですね。これはDB保存するメリットとなりえるのでしょうか。
単純にファイルを保存する場所のパーミッションや権限の設定で解決できそうではありますが。
何はともあれ、大変勉強になりました。
経験から答えます。
前提として、WEBサーバ(アプリケーションサーバ)にはファイルもDBも置きません。
ファイルに保存
・普通はこっち
・機能作成時は簡単
・アクセス制限を考えると簡単に<imgタグをはれないので一工夫必要。逆にいえば一工夫ですむ。</p>
・リサイズのモジュールなどを使用するときにファイルが対象になっている場合が多く、そのまま利用できる。
DB保存
・DBサーバを複数にしたときに苦労しなかった。ファイル保存では、自身で同期を取る必要が出てしまうが、
オラクルなどであれば、製品で提供されているため、楽。
・バックアップ、リカバリが楽。DBにひとつになっているのはそれだけですむので楽。
・スケーラブル。件数が増えたときのパフォーマンスがぜんぜん違う。ファイルで保存するときには、どのように保存するか(フォルダに分割するのか)留意しないと、突如遅くなったりする。
アクセス数は多くないとのことですので、ファイルで実装されるのが無難ではないでしょうか?
なるほど。非常に勉強になりました。ありがとうございます。
なるほど、大変勉強になりました。
少し違うかもしれませんが、ユーザーからたとえばウイルスが送信されたとして、そのウイルスはunix上のシステムシステムを破壊するものだとすると、DB保存していれば大丈夫ですが、ファイル保存だと危ないですね。これはDB保存するメリットとなりえるのでしょうか。
単純にファイルを保存する場所のパーミッションや権限の設定で解決できそうではありますが。
何はともあれ、大変勉強になりました。