web-dev-qa-db-ja.com

このアプリケーションのデータベースまたはファイルシステムに画像を保存する必要がありますか?

私はASP.NET MVC 4とSQL Server 2012を使用しています。これらのソリューションのどちらでも問題はありませんが、現在作成している特定のアプリケーションにどちらが適しているかを知りたいです。

図書館系のアプリを作っています。アプリケーションが保存する画像は次のとおりです。

  • ユーザーのプロフィール写真(ユーザーごとに1つ)
  • ライブラリのプロフィール写真(ライブラリごとに1つ)
  • ブック著者の写真(著者ごとに1つ)
  • ブックカバーの画像(1冊につき1枚)

保存される画像は、高品質である必要はありません。したがって、明らかに画像はアプリケーションの大部分ではなく、これを考慮して、現在データベースに画像を保存しています。私は私が大きな詐欺になると思う何かに気づきましたが。

画像はUrl.ActionLinkを使用して取得され、データベースに到達する前に(たとえば)bookIdパラメーターを受け入れるコントローラーアクションメソッドにつながり、その書籍の画像を取得して送り返します。そのため、ユーザーが本を検索し、最終的に本のリストと画像を取得する場合、画像を取得するアクションメソッドへの新しい呼び出しと、リストされた各画像のデータベースへの新しいクエリが存在します。

これを処理するより良い方法はありますか?データベースに画像を保持することを再検討する必要がありますか、それとも大きな問題ではありませんか?

編集:この質問は、anyタイプとは対照的に、非常に少ない画像データを処理するアプリケーションの特定のタイプに関係するため、重複とは見なしません( リンクされた質問 のように)アプリケーションの。もちろん、保存する画像データの量がわからない場合は、常にファイルシステムに画像を保存することをお勧めします。これはそのような場合ではありません。ここでの答えとそこにある答えの性質はこれを示しています。

10
Alternatex

なぜ両方しないのですか?データベースは、画像の裏付けとなる究極のストアです。パブリックサイドはdbからの単純な読み取りでもかまいませんが、それを簡単にリードスルーディスクキャッシュに拡張し、パフォーマンスを向上させるために多数のインフラストラクチャトリックを利用することもできます。

ここでの勝利は:

  • シンプルなデータバックアップ-データベースバックアップは楽しく簡単で、ファイルシステムに触れる必要はありません
  • よりシンプルな開発ストーリー-一連のファイルを処理する必要はありません。開発チームにデータベースのコピーを入手してください
  • イメージの書き込みが簡単-ファイルシステムは、権限から、dev-> qa-> productionから場所の変更、トランザクションの競合まで、PITAです。書き込みがデータベースに行われる場合、これらの問題の90%を解決します。
  • 最近のデータベースはそれを処理できます-数メガバイト以下で測定されるかなり典型的な画像ファイルサイズを話していると仮定すると、ほとんどの最近のデータベースシステムは非常にうまく処理できます。いくつかの古い記事があなたに信じさせるのはデータベース殺害の問題ではありません。
9
Wyatt Barnett

議論のどちらの側にも正当な懸念があるため、常に要件と制約を考慮してください。データ量、画像数、サイズ、安全性、復旧時間

インライン/ BLOBストレージ

上向き

  • バージョン管理/トランザクションの一貫性。これが重要な意味上の違いです。これはDBによって適切に処理されるため、ポイントインタイムリカバリが可能になります。ファイルシステムはこれを提供しないので、ロールバックする機能はありません。 (私はスタンドアロンのファイルシステムを指しているのではなく、コードからのトランザクション制御の問題を指している)。画像やドキュメントは、ユーザーエラーによって破損したり、同期しなくなったりして、2フェーズコミットの問題になります。一部のシステムは、外部リビジョン管理システムを追加することでこれを解決しますが、統合が必要です。
  • 実装を簡素化
  • すべてのアプリデータが自己完結型-Blobデータのフットプリントが扱いにくい場合を除き、システムのバックアップとリカバリまたは移行を簡素化します。ダンプ、バックアップ、エクスポート(DBの種類に関係なく)を実行し、新しいデータベースに移動するだけです。同期する外部ファイルはありません。
  • セキュリティ/アクセス制御はよりきれいです。画像BLOBへのアクセスは、データ行へのアクセスに固有です。ドキュメントがDBの外部にあり、HTTPサーバーにそれをフェッチさせた場合(MVCアプリの外)、並行性とスケーラビリティには優れているかもしれませんが、外部ファイルがDBであるため、承認が確実に適用されるように細心の注意を払いますデータ。大きなファイルが静的で多重化されたURLの下で行外に格納されている設計を監査しました。最初のテストシナリオは、認証なしで静的URLに直接アクセスすることです。安全なドキュメントをDBの外部に格納する場合は、それらを静的に提供せず、セキュリティポリシーがテナント間のイメージのアクセス制御をカバーしていることを確認してください。 HTTPサーバー認証は、システム全体の認証と統合する必要があります。これは、マルチテナントデータベースでは大きな問題です。シンプルな認証により、単一目的のシングルテナントシステムではそれほど心配する必要がありません。
  • データベースサーバーの表面積の削減-多くのシステムでは、DBはアプリサーバーから分離されており、その間にファイアウォールがあります。例として、すべてを単一のDBポート(1433/MSSQL)または(1521/Oracle)で提供できます。ファイルの場合、DBを別の層に移動する場合は、NFSまたはNASを使用するか、スケールアウトする場合はアプリサーバー間でファイルを複製する必要があります。

欠点

  • バックアップ時間-本当に大規模なデータベース(該当しない場合)の場合、バックアップとリカバリは苛立たしくなり、問題とコストがかかり始めます。それ以外の場合、小さなコアデータセットがあるかもしれませんが、多くのGBまたはTB=の画像データがある可能性があります。1つの一貫したデータベースとしてすべてを扱うことは、整合性の観点からはどちらも良いですが、バックアップには適していません。エンタープライズグレードのバックアップとリカバリでDBMSを使用する場合を除き、リカバリ(例:Oracle RMANとローリングバックアップ、EMC BCVまたはNetappスナップショット)。あるお客様では、DBが非常に大きくなったため、バックアップを停止し、地理的に冗長なレプリカにコミットしました。もう1つのよく知られているケースはスターバックスでした(DBAは論文をオンラインに掲載しました。これに興味があれば興味深いです)。
  • 回復までの時間(別名、回復時間目標または回復SLA)-これは多くの場合、クライアントによって定義されます。 DBAは、顧客がすでに宣言している場合は、それに戻る必要があります。安全でない画像を保存するためにデータベースのサイズに90%を追加すると、重要なデータのリカバリSLAに影響する場合は、実行しないでください。
  • 柔軟性が低い。 OSレベルのユーティリティ、シェルコマンドなどでドキュメントにアクセスするのは簡単ではありません。

個人的には、この文脈では、スケールはインラインDBストレージを優先して積み重ねられていると思います。 DBが大きくない場合は、すべてDBに保持してください。

5
codenheim

そのため、ユーザーが本を検索し、最終的に本のリストと画像を取得する場合、画像を取得するアクションメソッドへの新しい呼び出しと、リストされた各画像のデータベースへの新しいクエリが存在します。

それは良いことだと思います。画像はテキストよりも転送にはるかに時間がかかるため、ユーザーに両方のDBからの読み込みを待機させるのではなく、テキストを表示してから画像を個別に読み込むことができます。

また、アプリケーションが成功した場合は、Webアプリケーションを複数のサーバーで実行することもできます。その時点で、各サーバーはデータベースにアクセスできますが、他のサーバーのファイルシステムにはアクセスできません。

ただし、独自の画像テーブルで画像を分離することを検討する必要があります。本と同じテーブルに画像を保存しないでください。画像IDを保存し、それを使用して後で画像を取得するだけです。これは、データベースがディスク上のデータを管理する方法を考えると、はるかに効率的です。本に関連する画像をいつでも変更する場合は、この説明がかなり重要になります。

最後に、これらのことについての私の経験は、画像ストレージにコンテンツ配信ネットワークを使用したい状況に非常にすぐに遭遇することです(AWS CloudFrontまたはAzure CDNまたはCloudFlareを参照)。これは本当に両方の世界で最高です-アプリをトラブルさせることなく、URLから直接アクセスできる二次ストレージ-そしてそれほど多くの追加作業はありません画像を独自のテーブルに分離した場合、CDNへの移行は非常に簡単な変更です。

または、今すぐCDNソリューションを使用するだけで、もう心配する必要はありません。

4
pdr

SQLサーバー(2008以降)を使用している場合、それらをデータベースにblobとして保存するか、FILESTREAMを使用して保存できます。他のコメンテーターが指摘しているように、そのシナリオでは一貫性を管理する必要があるため、ディスクにファイルを適切に保存するアプローチは採用しません。

FILESTREAMの適切なリンクは、次の場所にあります。

FileStreamガイドライン

いくつかの一般的なルール:

SQL Serverでは、BLOBは、テーブルにデータを格納する標準のvarbinary(max)データ、またはデータをファイルシステムに格納するFILESTREAM varbinary(max)オブジェクトにすることができます。データのサイズと用途によって、データベースストレージとファイルシステムストレージのどちらを使用するかが決まります。つまり、簡単に言うと、これらはこの機能が最も適している典型的なシナリオです。

  • 平均サイズが1MB以上のBLOBを保存する場合。
  • 高速読み取りアクセスが厳格な場合。
  • アプリケーションの中間層コードからBLOBにアクセスする必要がある場合。

全体として、他のオプションに対するFILESTREAMの主な利点は次のとおりです。

  • BLOBの格納と取得は、リレーショナルデータと共に単一のデータストアで行われます。
  • はい、BLOBはデータベースのバックアップと復元に含まれています。
  • BLOBとリレーショナルデータの挿入、更新、削除は、同じデータベーストランザクションで行われます。
  • Varbinary(max)列の最大サイズ2 GBは適用されません。 NTFSファイルシステムの使用可能なスペースによってのみ制限されます。
  • SQL Serverのバッファープールメモリは、BLOBの操作には使用されません。以前のバージョンでは、大きなBLOBがこのメモリを大量に消費する可能性がありました。
  • すべてのBLOBアクセスは.NETコードから実行できるため、中間層コードでこれらのオブジェクトを簡単に操作できます。
  • NTFSファイルシステムは、SQL Serverよりも効率的に大きなBLOBを保存および取得できます。

それでも、FILESTREAMの実装にはいくつかの制限が適用されます。

  • FILESTREAM機能は、データベースミラーリングではサポートされていません。
  • FILESTREAMデータコンテナーは、同じディレクトリを共有したり、入れ子にすることはできません。
  • 透過的データ暗号化(TDE)が有効になっている場合でも、FILESTREAMデータは暗号化されません。
3
Jon Raynor

画像をデータベースに保存しないことをお勧めします。

それはデータベースが意図しているものではありません-他のデータに関連するのはリレーショナルデータではありません。データベースブロブ列内では、簡単に膨大なスペースを取り、操作が困難です。

データベースを使用して、名前、タイムスタンプ、メタデータ、ファイルの場所を保存しています。次に、そのファイルに画像を保存してアクセスしますlocation/name

私はこれを数年前に現実の世界で経験し、他の多くの人と一緒に、データベースに画像を保存することは悪いアプローチであるという結論に達しました。バージョン管理と履歴については、ソース管理に参照を含むコードを用意し、他と同様に管理します。したがって、各画像の名前を変更し、日付スタンプを使用して、別の画像にまったく同じファイル名を再利用しないでください。

すべての画像が原因でデータベースが大きくなりすぎたため、この間に開始する多くの人々はしばらくしてからスイッチをメインにしなければなりません。これは、ストレージのニーズ、サーバー、CPU、および場合によってはネットワークトラフィックに波及効果をもたらします。また、地理的な場所やトラフィックなどを考慮できるクラウドベースのファイルシステムストレージを使用することが難しくなります。これらの手法は、会社が成長するにつれて重要になり、データベースに画像を含めると、オプションが大幅に制限される可能性があります。

結論として、画像データの量が少ない小規模プロジェクトに適しています。大規模なショップや大量のデータには適していません。

3
Michael Durrant