2009-04-09 15 views
8

Railsを使用すると、データベースではなくファイルシステムに添付ファイルを保存する必要があるのはなぜですか?データベースは私にとっては簡単だと思われます。ファイルシステムのパスや構造などを気にする必要はありません。ブロブフィールドを見るだけです。しかし、ほとんどの人はファイルシステムを使用しているように思えます。私はそれが実現しないようにいくつかの利点があるか、あるいはそのようなストレージにデータベースを使用することにはいくつかの欠点があると思います。 (この場合、私はpostgresを使用しています)。Rails:データベースにバイナリファイルを保存する

答えて

26

これはかなり標準的な設計質問であり、本当に「真の答え」はありません。

私が典型的に従うルールは、「データはデータベースに格納され、ファイルはファイルに格納されます」です。検討事項のいくつかは心に留めておくべき

  1. ファイルはデータベースに格納されている場合、どのようにあなたはhttp経由でそれを提供するために行くの?コンテンツタイプ、ファイル名などを設定する必要があることを覚えておいてください。ファイルシステム上のファイルであれば、Webサーバーはあなたのためにすべてのものを処理します。非常に迅速かつ効率的(おそらくカーネル空間でさえ)、解釈されるコードは必要ありません。

  2. ファイルは通常大きいです。大きなデータベースは確かに実行可能ですが、バックアップが遅くて不便です。なぜ、データベースを巨大にする必要がないのですか?

  3. 2.と同じように、複数のマシンにファイルをコピーするのは本当に簡単です。クラスタを実行しているとします。マスターマシンからスレーブにファイルシステムを定期的にrsyncして、標準的な静的httpサービスを使用できます。もちろん、データベースはクラスタ化することもできますが、必ずしも直感的であるとは限りません。

  4. 3の裏側で、​​既にデータベースをクラスタ化している場合は、クラスタ化されたファイルを処理する必要がありますが、管理上の複雑さです。これは、DBにファイルを格納することを検討する理由となります。

  5. データベース内のBLOBデータは通常不透明です。フィルタリング、並べ替え、グループ化はできません。これにより、データベースに格納する価値が低下します。

  6. データベースでは、並行処理を理解しています。標準的なトランザクション分離モデルを使用して、2人のクライアントが同じファイルを同時に編集しようとしないようにすることができます。これはいいかもしれない。あなたがロックファイルを使うことができなかったとは言えませんが、今はあなたが理解しなければならないことが2つあります。ファイルシステム内のファイルは、通常のツールで開くことができます。 Vi、Photoshop、Word、あなたが必要とするものは何でも。これは便利です。その単語の文書をブロブフィールドからどうやって開くのですか?

  7. 権限。ファイルシステムにはパーミッションがあり、後ろに苦労する可能性があります。逆に、あなたのアプリケーションに役立つかもしれません。あなたのウェブサーバがあなたのアプリケーションとは異なる権限で動作することがほぼ保証されているので、あなたが7を利用しているならば、アクセス権は本当にあなたを傷つけます。

  8. キャッシュ(下のサラ・メイから)。これは、上記のhttpの質問にクライアント側でプレイします(あなたは生涯を正しく設定することを忘れないでしょうか?)。サーバー側では、ファイルシステム上のファイルは非常によく理解され、最適化されたアクセスパターンです。大規模なblobフィールドはデータベースによって最適化されている場合と最適化されていない場合があります。データベースからWebサーバーへの追加のネットワークトリップもほとんどないことが保証されています。

つまり、人々はファイルのようなイディオムを最もよくサポートするため、ファイルシステムにファイルシステムを使用する傾向があります。しかし、ファイルシステムはますますデータベースに似てきているので、最終的に完全な収束を見ることはまったく驚いていません。

+0

ありがとう、Erik。それは非常に有用かつ包括的な回答でした。 –

+0

7.サーバーで直接作業することを意味していますか?ファイルとして、Photoshopで開く前にダウンロードすることもできます。あるいは、私のバージョン管理システムが私のためにそれを行うでしょう。 – Luc

+0

複製されていないローカルファイルシステムに物を格納すると、12factorスタイルのアプリケーションが壊れてしまうことがあります。 S3/CloudFrontまたは同様のクローンバックエンドに添付ファイルを格納することは、大部分の(ただしすべてではない)ユースケースを処理する方法です。 CarrierWave、Paperclipなどは、これらの違いを抽象化するのに役立ちます。 – Barry

2

エリックの答えは素晴らしいです。また、キャッシングを行う場合は、静的ファイルをキャッシュする方が、データベースの内容をキャッシュする方がはるかに簡単で簡単です。

0

Paperclipなどのプラグインを使用している場合は、何も心配する必要はありません。ファイルシステムと呼ばれるものがあります。これは、ファイルがどこに行くのかです。ちょっと難しいというだけでも、ファイルを間違った場所に置く必要はありません。クリップ(または他の同様のプラグイン)を使うと難しくありません。だから、gogoファイルシステム!

+1

適切なユーザーだけがファイルを閲覧/アクセスできるようにするにはどうすればよいですか?Paperclipはこれを処理しますか? – Greg

+0

これは極端なケースです。これまでfacebookは画像を保護していません(画像に非常に邪悪なURLを与える以外に)。 –

+0

これを行う1つの方法は、プロダクション環境でApacheサーバの背後にファイルを置くことです。.htaccessファイルでこれを閉じることができます。問題?ファイルを取得する。私はこれがレールでは可能だがPHPでは可能かどうかはわかりませんが、ユーザーがそれを見る許可を持っているかどうかを確認した後、.htaccessで保護されたディレクトリからファイルを取得できます。 PHPスクリプトは、もちろん、別のパブリックディレクトリにあります。 –

6

ファイルシステムにファイルを使用することについてのアドバイスはありますが、ここで何か考えてみましょう。機密または安全なファイル/添付ファイルを保管している場合、DBを使用することは実際には唯一の方法です。私はデータをファイルに出力することができないアプリケーションを構築しました。セキュリティ上の理由から、DBに格納する必要があります。サーバ/マシン上のユーザがファイルシステムに残しておくことはできません。 Oracleのような高級DBを使用すると、そのデータをきちんとロックし、適切なユーザーだけがそのデータにアクセスできるようにすることができます。

他の点は非常に有効です。単にアバター画像や非機密情報のようなことをしているのであれば、ファイルシステムは一般に、ほとんどのプラグインシステムにとってより高速で便利です。

DBは、ファイルを送信するための設定が非常に簡単です。それはもう少し仕事ですが、あなたが何をしているのか分かっていれば、ほんの数分です。ですから、ファイルシステムは全体的にIMOに向かうより良い方法ですが、セキュリティや機密データが大きな関心事である場合、DBは唯一実行可能な選択肢です。

+0

これは本当です。ファイルシステムとデータベース間でセキュリティルールを同時に同期しようとするのは、最高の状態では困難です。 – easel

+0

それは不可能かもしれませんが、Linuxのようなものがあります。ファイルシステム上のhtaccessファイルを使用して、不正なWeb閲覧者がファイルを参照しないようにするか、公開Webサーバーディレクトリからファイルを保存して、そこに参照リンクを設定することができます。 PHPの場合、適切なパーミッションがあれば、OSに公開されていないどこからでもファイルを引き出すことができます。 –

1

ブロブストアの問題は何もわかりません。そこからファイルシステムストアをいつでも再構築することができます。システムが使用されている間に、ローカルのWebサーバーにその内容をキャッシュすることによって。 しかし、正式なストアは常にデータベースでなければなりません。つまり、データベースに投げ込んでソース管理からコードをエクスポートすることで、アプリケーションを導入することができます。完了しました。 Webサーバーを追加することはまったく問題ありません。

+0

生産経験に基づいて、私はこの答えが正解であると信じています。 – cfeduke

関連する問題