そのため、DBに画像を大量に保存するアプリを使用しています。これについてどう思いますか?私は、DBに直接保存するよりも、ファイルシステムに場所を保存するタイプです。
長所/短所は何だと思いますか?
そのため、DBに画像を大量に保存するアプリを使用しています。これについてどう思いますか?私は、DBに直接保存するよりも、ファイルシステムに場所を保存するタイプです。
長所/短所は何だと思いますか?
回答:
何TBもの画像を管理するいくつかのアプリケーションを担当しています。データベースへのファイルパスの保存が最適であることがわかりました。
いくつかの問題があります:
ほとんどの問題と同様に、思ったほど簡単ではありません。画像をデータベースに保存することが理にかなっている場合があります。
一方、関連する問題があります
ファイルストア。Facebookのエンジニアはそれについて素晴らしい話をしました。1つのポイントは、ディレクトリ内のファイルの実際的な制限を知ることでした。
これは少し長いショットかもしれませんが、SQL Server 2008を使用している(または使用を計画している)場合は、新しいFileStreamデータ型を確認することをお勧めします。
FileStreamは、DBへのファイルの保存に関する問題のほとんどを解決します。
ただし、SQLの「透過的データ暗号化」はFileStreamオブジェクトを暗号化しないため、それが考慮事項である場合は、varbinaryとして格納するだけの方がよい場合があります。
MSDN記事から:
Transact-SQLステートメントでは、FILESTREAMデータを挿入、更新、クエリ、検索、およびバックアップできます。Win32ファイルシステムインターフェイスは、データへのストリーミングアクセスを提供します。
FILESTREAMは、NTシステムキャッシュを使用してファイルデータをキャッシュします。これにより、FILESTREAMデータがデータベースエンジンのパフォーマンスに与える影響を軽減できます。SQL Serverバッファープールは使用されません。したがって、このメモリはクエリ処理に使用できます。
DB内のファイルパスは間違いなく進むべき道です。TBの画像を使用しているお客様から、DBに大量の画像を保存しようとすると悪夢になるという話を何度も耳にしました。パフォーマンスヒットだけでは大きすぎます。
私の経験では、最も簡単な解決策は、主キーに従って画像に名前を付けることです。そのため、特定のレコードに属する画像を簡単に見つけることができ、その逆も同様です。しかし、同時に、画像についてはデータベースに何も保存していません。
ここでの秘訣は熱狂者にならないことです。
ここで注意すべき点の1つは、プロファイルシステムキャンプの誰も特定のファイルシステムをリストしていないことです。これは、FAT16からZFSまでのすべてのものがすべてのデータベースに勝るとも劣らないことを意味しますか?
番号。
真実は、私たちが生の速度だけを話しているときでさえ、多くのデータベースが多くのファイルシステムを打ち負かすということです。
正しい行動方針は、正確なシナリオに対して正しい決定を行うことです。そのためには、いくつかの数値といくつかのユースケースの見積もりが必要になります。
参照整合性とACIDコンプライアンスを保証する必要がある場所では、データベースに画像を保存する必要があります。
データベースに保存されている画像とその画像に関するメタデータが同じファイルを参照していることをトランザクションで保証することはできません。言い換えると、ファイルシステム上のファイルがメタデータと同時に同じトランザクションでのみ変更されることを保証することは不可能です。
他の人が言ったように、SQL 2008にはFilestreamタイプが付属しているため、dbにファイル名または識別子をポインターとして保存し、ファイルシステムにイメージを自動的に保存できます。
古いデータベースを使用している場合、それをblobデータとして保存していると、機能の検索方法でデータベースから何も取り出せなくなるので、おそらく最良の方法です。ファイルシステムにアドレスを保存し、その方法でイメージを保存します。
この方法では、ファイルシステムのスペースを正確に保存するだけで、ファイルシステムのスペースも圧縮するだけなので、ファイルシステムのスペースも節約できます。
また、dbヒットなしでファイルシステム内の未加工画像を参照できるようにするいくつかの構造または要素を使用して保存するか、ファイルを別のシステム、ハードドライブ、S3または別のシナリオに一括転送することもできます。プログラムを使用しますが、構造を維持します。ストレージを増やしようとするときに、イメージをdbから取り出そうとすることはありません。
おそらく、それはまた、あなたがあなたのウェブエンジン/プログラムに一般的にヒットする画像URLに基づいていくつかのキャッシング要素を投げることを可能にするでしょう、それであなたもそこにあなた自身を保存しています。
頻繁に編集されない小さな静的画像(数メガ以下)は、データベースに保存する必要があります。この方法には、移植性(データベースと一緒に画像が転送される)、バックアップ/復元が簡単(データベースと一緒に画像がバックアップされる)、スケーラビリティ(数千の小さなサムネイルファイルを含むファイルシステムフォルダーがスケーラビリティの悪夢のように聞こえる)などのいくつかの利点があります。私)。
データベースから画像を提供するのは簡単です。DBサーバーから返されたバイト配列をバイナリストリームとして提供するhttpハンドラーを実装するだけです。
このトピックに関する興味深いホワイトペーパーを次に示します。
BLOBを使用するかしないか:データベースまたはファイルシステムのラージオブジェクトストレージ
答えは「場合によります」です。確かに、データベースサーバーとBLOBストレージへのアプローチに依存します。また、blobに格納されているデータのタイプ、およびそのデータへのアクセス方法にも依存します。
小さいサイズのファイルは、データベースをストレージメカニズムとして使用して効率的に格納および配信できます。大きなファイルは、特に頻繁に変更/更新される場合は、ファイルシステムを使用して保存するのが最適です。(ブロブの断片化は、パフォーマンスに関して問題になります。)
ここで、覚えておくべき追加のポイントがあります。BLOBを格納するためのデータベースの使用をサポートする理由の1つは、ACIDへの準拠です。ただし、ホワイトペーパー(SQL Serverの一括ログ記録オプション)でテスターが使用したアプローチでは、SQL Serverのスループットが2倍になり、blobデータがログに記録されなかったため、ACIDの「D」が「d」に効果的に変更されました。トランザクションの最初の書き込み。したがって、システムの完全なACIDコンプライアンスが重要な要件である場合は、ファイルI / OとデータベースBLOB I / Oを比較するときに、データベース書き込みのSQL Serverスループット値を半分にします。
まだ誰も言及していないが、注目に値することの1つは、ほとんどのファイルシステムに大量の画像を保存することに関連する問題があることです。たとえば、上記のアプローチを採用し、各画像ファイルに主キーにちなんで名前を付けた場合、ほとんどのファイルシステムでは、非常に多数の画像に到達したときにすべての画像を1つの大きなディレクトリに配置しようとすると問題が発生します(たとえば、数十万または数百万)。
これに対する一般的な解決策の1つは、それらをサブディレクトリのバランスの取れたツリーにハッシュすることです。
誰も言及していないことは、DBがアトミックアクション、トランザクションの整合性を保証し、同時実行性を扱うことです。参照整合性でさえ、ファイルシステムではウィンドウの外にあります。ファイル名が本当に正しいことをどのようにして知るのでしょうか。
ファイルシステムに画像があり、新しいバージョンを書き込んだり、ファイルを削除したりしているときに誰かがファイルを読み取っている場合-どうなりますか?
管理(バックアップ、レプリケーション、転送)も簡単なので、ブロブを使用します。彼らは私たちにとってうまくいきます。
私が働いていた会社では、1億5500万枚の画像をOracle 8i(当時は9i)データベースに保存していました。7.5TB相当。
前提:アプリケーションはWeb対応/ Webベースである
誰も本当にこれについて言及していないことに驚いています...専門家である他の人にそれを委任してください-> サードパーティのイメージ/ファイルホスティングプロバイダーを使用してください。
次のような有料オンラインサービスにファイルを保存します
ここでこれについて話している別のStackOverflowスレッド。
このスレッドでは、サードパーティのホスティングプロバイダーを使用する理由について説明します。
それはとても価値があります。彼らはそれを効率的に保管します。サーバーからクライアントのリクエストなどにアップロードされる帯域幅はありません。
SQL Server 2008を使用しておらず、特定の画像ファイルをデータベースに配置する確かな理由がある場合は、「両方」のアプローチをとり、ファイルシステムを一時キャッシュとして使用し、データベースをマスターリポジトリとして使用できます。 。
たとえば、ビジネスロジックは、提供する前にイメージファイルがディスクに存在するかどうかをチェックし、必要に応じてデータベースから取得できます。これにより、複数のWebサーバーの機能を利用でき、同期の問題が少なくなります。
これが「現実の世界」の例のどれくらいかはわかりませんが、現在、カードの画像を含むトレーディングカードゲームの詳細を保存するアプリケーションがあります。データベースのレコード数は現在までのところ2851レコードのみですが、特定のカードが複数回リリースされ、代替のアートワークがあるという事実を踏まえると、アートワークの「プライマリスクエア」をスキャンしてから動的にスキャンする方が実際にはサイズがより効率的でした要求されたときにカードの境界線とその他の効果を生成します。
この画像ライブラリの最初の作成者は、リクエストに基づいて画像をレンダリングするデータアクセスクラスを作成し、表示と個々のカードを非常に高速に処理しました。
これにより、新しいカードがリリースされたときの展開/更新も簡単になります。イメージのフォルダー全体を圧縮してパイプに送信し、適切なフォルダー構造が作成されるようにする代わりに、データベースを更新してユーザーに再度ダウンロードしてもらうだけです。現在、これは最大56MBのサイズで、これは素晴らしいことではありませんが、将来のリリースのために増分更新機能に取り組んでいます。さらに、ダイヤルアップを介してダウンロードの遅延なしにアプリケーションを取得できるようにするアプリケーションの「イメージなし」バージョンがあります。
このソリューションは、アプリケーション自体がデスクトップ上の単一のインスタンスとしてターゲットに設定されているため、これまでのところ優れています。このすべてのデータがオンラインアクセス用にアーカイブされているWebサイトがありますが、同じソリューションを使用することは決してありません。ファイルへのアクセスは、画像に対して行われる要求の頻度と量に合わせて拡張できるため、望ましいと思います。
うまくいけば、これはあまり意味のないことですが、私はこのトピックを見て、比較的成功した小規模/中規模アプリケーションから私の洞察を提供したいと思いました。
SQL Server 2008は、両方の長所を兼ね備えたソリューションを提供します。ファイルストリームデータタイプ。
通常のテーブルのように管理し、ファイルシステムのパフォーマンスを確保します。
保存する画像の数とサイズによって異なります。私は過去にデータベースを使用して画像を保存しましたが、私の経験はかなり良好です。
IMO、データベースを使用して画像を保存する長所は、
A.画像を保持するためにFS構造は必要ありません
。B。より多くのアイテムを保存する場合、データベースインデックスはFSツリーよりもパフォーマンスが優れています
。C。スマートに調整されたデータベースは、クエリ結果をキャッシュするのに優れています
。また、レプリケーションが設定されていて、コンテンツがユーザーの近くのサーバーから配信されている場合にもうまく機能します。このような場合、明示的な同期は必要ありません。
画像が小さくなり(たとえば64k未満)、dbのストレージエンジンがインライン(レコード内)BLOBをサポートする場合、間接指定が不要なため、パフォーマンスがさらに向上します(参照の局所性が実現されます)。
少数の巨大なサイズの画像を扱う場合、画像を保存することは悪い考えかもしれません。画像をデータベースに保存する際のもう1つの問題は、作成、変更日などのメタデータをアプリケーションで処理する必要があることです。
最近、PDF / WordファイルをMySQLテーブルに保存するPHP / MySQLアプリを作成しました(これまでのところ、ファイルあたり最大40MB)。
長所:
短所:
私は自分の実装を成功と呼びます。バックアップ要件を処理し、プロジェクトのレイアウトを簡素化します。アプリを使用する20〜30人にとってパフォーマンスは良好です。
私の経験では、データベースに保存されている画像と、パスがdbに保存されているファイルシステム上の画像の両方を管理する必要がありました。
最初のソリューションであるデータベース内の画像は、データアクセスレイヤーがデータベースオブジェクトのみを処理する必要があるため、多少「クリーン」です。しかし、これは、少ない数を処理する必要がある場合にのみ有効です。
明らかに、バイナリラージオブジェクトを処理するときのデータベースアクセスのパフォーマンスは低下しており、データベースディメンションは大幅に増大し、再びパフォーマンスが低下します。通常、データベーススペースはファイルシステムスペースよりもはるかに高価です。
一方、大きなバイナリオブジェクトをファイルシステムに保存すると、データベースとファイルシステムの両方を考慮する必要のあるバックアップ計画が作成されます。これは、一部のシステムでは問題になる可能性があります。
ファイルシステムを使用するもう1つの理由は、画像データ(またはサウンド、ビデオなど)をサードパーティのアクセス権と共有する必要がある場合です。現在、私は「外部から」アクセスする必要がある画像を使用するWebアプリを開発しています"バイナリデータを取得するためのデータベースアクセスが単純に不可能になるような方法で私のWebファーム。したがって、選択を促す設計上の考慮事項がある場合もあります。
また、バイナリオブジェクトにアクセスするときに権限と認証を処理する必要がある場合は、この選択を行う際に考慮してください。これらの要件は、通常、データがdbに格納されているときに簡単に解決できます。
かつては画像処理アプリケーションに携わっていました。アップロードした画像は、/ images / [今日の日付] / [ID番号]のようなディレクトリに保存しました。ただし、画像からメタデータ(exifデータ)を抽出し、タイムスタンプなどと共にデータベースに保存しました。
以前のプロジェクトでは、イメージをファイルシステムに保存していたため、バックアップ、レプリケーション、およびファイルシステムとデータベースとの同期が取れなくなり、多くの問題が発生しました。
私の最新のプロジェクトでは、データベースに画像を保存し、それらをファイルシステムにキャッシュしています。これまで問題はありませんでした。
次に、ファイルパスに関する推奨事項。私は、大規模なアセットコレクションを管理する必要があるいくつかのプロジェクトに取り組んできました。物事をDBに直接保存しようとすると、長期的に苦痛と不満が生じました。
それらをDBに格納することに関して私が考えることができる唯一の本当の「プロ」は、個々の画像アセットの容易さの可能性です。使用するファイルパスがなく、すべての画像がDBから直接ストリーミングされる場合、ユーザーがアクセスしてはならないファイルを見つける危険はありません。
それは、Webからアクセスできないファイルストアからデータを取得する中間スクリプトで解決するほうがよいようです。したがって、DBストレージは本当に必要ではありません。
画像をデータベースに保存しても、画像データはファイルシステムのどこかに移動しますが、直接アクセスできないように不明瞭になります。
+ ves:
-ves:
どちらの方法も一般的であり、実践されています。長所と短所を見てください。どちらにしても、欠点を克服する方法を考える必要があります。データベースに保存することは、通常、データベースパラメータを調整し、ある種のキャッシュを実装することを意味します。ファイルシステムを使用するには、ファイルシステムとデータベースの同期を維持する方法を見つける必要があります。