やるべきこと、やるべきでないこと:画像をデータベースに保存 [複製]

StackOverflow https://stackoverflow.com/questions/815626

  •  03-07-2019
  •  | 
  •  

質問

この質問にはすでに答えがあります:

Web アプリケーションのコンテキストでは、私の古い上司は、画像そのものではなく、画像への参照をデータベースに入れるように常に言っていました。私は、URL を保存することと、画像自体を DB に保存するのは良いアイデアですが、私が現在働いている場所では、大量の画像をデータベースに保存しています。

私が考えられる唯一の理由は、おそらくその方が安全なのではないでしょうか?誰かに URL への直接リンクを与えたくないですか?ただし、その場合は、asp.net のハンドラーのように、Web サイト/サーバーでいつでも画像を処理できるようにして、ユーザーが画像を表示するために認証を必要とするようにすることができます。また、データベースから画像を取り出すことでパフォーマンスが低下するのではないかとも考えています。画像をデータベースに保存することが良いアイデアであるか、あまり良いアイデアでないのか、他に理由はありますか?


完全な重複: ユーザー画像:データベースまたはファイルシステムストレージ?
完全な重複: 画像をデータベースに保存する:そうか、いや?
完全な重複: 画像をデータベースまたはフォルダーに保存する必要がありますか?
完全な重複: バイナリ データをデータベースまたはフォルダーに保存しますか?
完全な重複: 写真をファイルとして保存しますか、それとも Web アプリのデータベースとして保存しますか?
完全な重複: 少数の画像を保存する:BLOBかFS?
完全な重複: イメージをファイルシステムまたはデータベースに保存しますか?

役に立ちましたか?

解決

場合によっては画像を取得する必要があり、画像は複数の異なるWebサーバーで利用可能でなければなりません。しかし、私はそれがほとんどだと思います。

  • 複数のサーバーで使用可能にする必要がない場合は、常にファイルシステムに配置することをお勧めします。
  • 複数のサーバーで使用可能にする必要があり、実際にシステムに何らかの負荷がある場合、何らかの分散ストレージが必要になります。

ここでは、データベースを活用することでシステムに複雑さを追加することを避けることができるエッジケースについて話しています。

それ以外は、しないでください。

他のヒント

画像をデータベースに入れることの長所。

  1. トランザクション。 BLOBを保存すると、他のDBデータと同様にBLOBをコミットできます。つまり、関連付けられたメタデータのいずれかと共にBLOBをコミットでき、2つが同期していることが保証されます。ディスク容量が足りなくなったら?コミットしません。ファイルが完全にアップロードされませんでしたか?コミットしません。愚かなアプリケーションエラー?コミットしません。画像とそれらに関連するメタデータの一貫性を保つことがアプリケーションにとって重要な場合、DBが提供できるトランザクションは恩恵を受けることができます。

  2. 管理する1つのシステム。メタデータとブロブをバックアップする必要がありますか?データベースをバックアップします。それらを複製する必要がありますか?データベースを複製します。部分的なシステム障害から回復する必要がありますか? DBをリロードし、ログをロールフォワードします。 DBが一般にデータにもたらすすべての利点(ボリュームマッピング、ストレージ制御、バックアップ、レプリケーション、リカバリなど)は、ブロブに適用されます。一貫性の向上、管理の容易化。

  3. セキュリティ。データベースには、活用できる非常にきめ細かいセキュリティ機能があります。スキーマ、ユーザーロール、「読み取り専用ビュー」のようなものも。データのサブセットへの安全なアクセスを提供します。これらの機能はすべて、ブロブを保持するテーブルでも機能します。

  4. 集中管理。 #2に関連していますが、基本的には(十分な能力がないかのように)DBAが1つのことを管理します:データベース。最新のデータベース(特に大きなデータベース)は、複数のマシンにまたがる大規模なインストールで非常にうまく機能します。単一の管理ソースにより、手順が簡素化され、知識の伝達が簡素化されます。

  5. 最新のデータベースは、ブロブをうまく処理します。データ層のBlobのファーストクラスサポートにより、BlobをDBからクライアントに簡単にストリーミングできます。できる操作がありますが、「吸い込む」ことができます。ブロブ全体を一度に、その機能が必要ない場合は、使用しないでください。 DBのSQLインターフェイスを調べて、その機能を活用してください。 「大きな文字列」のように扱う理由はありません。モノリシックに処理され、ブロブを大きなメモリゴブリング、キャッシュスマッシングボムに変換します。

  6. 画像専用のファイルサーバーをセットアップできるように、データベースに専用のblobサーバーをセットアップできます。専用のディスクボリューム、専用のスキーマ、専用のキャッシュなどを提供します。DB内のデータはすべて同じではないか、同じように動作します。すべて同じように構成する理由はありません。優れたデータベースでは、きめ細かな制御が可能です。

DBからのblobの提供に関する主な点は、HTTPレイヤーが実際にすべてのHTTPプロトコルを活用してサービスを実行することです。

単純な実装の多くは、単にblobを取得し、それらをソケットに大量にダンプします。しかし、HTTPには、ストリーミング画像などに適した重要な機能がいくつかあります。特に、ヘッダー、ETag、チャンク転送をキャッシュして、クライアントが「ピース」を要求できるようにします。ブロブの。

HTTPサービスがこれらのすべてのリクエストを適切に受け入れ、DBが非常に優れたWeb市民になることができることを確認してください。 HTTPサーバーで提供するためにファイルシステムにファイルをキャッシュすることにより、「無料」でこれらの利点のいくつかを得ることができます。 (優れたサーバーは「静的」リソースに対してとにかくそれを行うので)、そうする場合は、画像の変更日などのことを尊重することを確認してください。

たとえば、誰かが2009年1月1日に作成された画像であるspaceshuttle.jpgを要求します。これは、要求日、たとえば2009年2月1日にファイルシステムにキャッシュされます。 (FIFOポリシーなど)、そして誰かが、2009年3月1日に再びそれを要求します。さて、2009年3月1日の「作成日」がありますが、作成日は実際には1月1日でしたが、特にキャッシュが大幅に変わる場合、Ifを使用しているクライアント-修正されたh

データベースに画像を保存する(または言及する)場合、データベースの専門家の大部分があなたを指でひっくり返すことを理解しています。はい、あらゆる種類のバイナリデータの大きなブロックのリポジトリとしてデータベースを使用する場合、パフォーマンスとストレージへの影響は間違いありません(画像は正規化できないデータの最も一般的なビットである傾向があります)。ただし、画像のデータベースストレージが許可されるだけでなく、賢明な状況が最も確実にあります。

たとえば、私の以前の仕事では、ユーザーが書き込み中のレポートのいくつかの異なるポイントに画像を添付するアプリケーションがあり、それらの画像は完了時に印刷する必要がありました。これらのレポートはSQL Serverレプリケーションを介して移動されたため、複数のシステムとサーバー間でこれらのイメージとファイルパスを何らかの信頼性で管理しようとすると、頭痛の種になります。それらをデータベースに保存すると、すべての「無料」が得られました。レポートツールは画像を取得するためにファイルシステムにアクセスする必要がありませんでした。

私の一般的なアドバイスは、どちらかのアプローチに限定せず、状況に合ったテクニックを使用することです。ファイル システムはファイルの保存に非常に優れており、データベースは要求に応じて一口サイズのデータ​​の塊を提供することに非常に優れています。一方、私の会社の製品の 1 つは、アプリケーションの状態全体をデータベースに保存する必要があるため、添付ファイルもデータベースに保存されることになります。当社の DB サーバー (SQL Server 2005) を使用すると、大規模な顧客やデータベースであっても、目に見えるパフォーマンスの問題がまだ発生していません。

Microsoft の SQL 2008 では、FileStream 機能により両方の長所を利用できます。チェックしてみる価値があるかもしれません。 http://technet.microsoft.com/en-us/library/bb933993.aspx

画像をデータベースに保存する利点の1つは、システム間で移植可能で、ファイルシステムのレイアウトに依存しないことです。

最も単純で最もパフォーマンスが高く、最もスケーラブルなソリューションは、ファイルシステムに画像を保存することです。セキュリティが懸念される場合は、Webサーバーからアクセスできない場所にそれらを配置し、セキュリティを処理してファイルを提供するスクリプトを記述します。

ウェブ/アプリサーバーとDBサーバーが異なるマシンであると仮定すると、DBにイメージを配置することでいくつかのヒットが発生します。(1)2つのマシン間のネットワーク遅延、(2)DB接続オーバーヘッド、(3)消費提供される画像ごとに追加のDB接続。最後の点についてもっと懸念します。サイトが多くの画像を提供する場合、Webサーバーは多くのDB接続を消費し、接続プールを使い果たす可能性があります。

アプリケーションが複数のサーバーで実行されている場合、画像の参照コピーをデータベースに保存し、ファイルシステムのオンデマンドでキャッシュします。そうすることで、ファイルシステムを横方向に同期しようとするよりも、エラーが発生しやすいロバの痛みがはるかに少なくなります。

アプリケーションが単一のサーバー上にある場合、ファイルシステムに固執し、データベースにデータへのパスを維持させます。

もちろん、ほとんどのSQLデータベースは画像を提供することを念頭に置いて設計されているわけではありませんが、データベースに保存することに関してある程度の利便性があります。

たとえば、すでにデータベースが実行されており、レプリケーションが構成されている場合。 rsyncまたはnfsベースのファイルシステムレプリケーションを実行しようとするのではなく、即座にHAイメージストアがあります。また、ファイルをディスクに書き込むための多数のWebプロセス(またはいくつかの新しいサービスの設計)を使用すると、複雑さが少し増加します。本当にそれはただ動く部分です。

少なくとも、画像に関する「メタ」データ(アクセス権、所有者など)と実際のデータを異なるテーブルに分けて保管することをお勧めします。データを後から保存します。何らかのCDNまたはキャッシングと組み合わせることで、ある程度まではかなり良いパフォーマンスが得られるはずです。したがって、このアプリケーションがどれだけスケーラブルである必要があるか、そしてそれを実装のしやすさとどのようにバランスさせるかにかかっていると思います。

URLを保存する必要はありません(安全でないと思われる場合)。他の場所で画像を参照する一意のIDを保存できます。

データベースストレージは、ファイルシステムよりも保守が高価で高価になる傾向があります。したがって、データベースに多くの画像を保存しません。

データベースにテラバイトの画像データが保存されている場合、災害復旧はまったく楽しいものではありません。データをより信頼性の高いものにするためのより良い方法を見つけた方がいいでしょう...もちろん、複製などの際にすべてのオーバーヘッド(上記)が増加します...

やらないでください!

これは本当にKISS(単純な愚かさを保つ)問題のようです。ファイルシステムは、画像ファイルの保存を簡単に処理できるように作られていますが、データベースで行うのは簡単ではなく、データを台無しにするのは簡単です。ファイルのセキュリティを心配するだけで、パフォーマンスとSQLのすべての難易度とレンダリングが必要になるのはなぜですか? NFSまたはCIFSを使用して、混合システムを処理することもできます。ファイルシステムは成熟したテクノロジーです。はるかにシンプルで堅牢。

デモンストレーションアプリケーション用にデータベースに画像を保存しました。私がやった理由はセキュリティでした-あるべきではないレコードを削除することは大きな問題ではありませんでしたが、あるべきでないファイルを削除することは問題だったかもしれません!

パフォーマンスが問題になった場合、不正なファイルの削除が本当の可能性であるかどうかを調査していました。

定期的にデータベースから引き出される画像である場合、私は常にファイルシステムを使用しようとします。

たまに取り出す必要がある画像で、データベースに保存しておくと作業が楽になりますが、これにはまったく問題はありません。

  • データ用データベース
  • ファイルのファイルシステム
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top