アップロードされた画像、SQLデータベース、またはディスクファイルシステムを保存するのに最適な場所は何ですか?
-
20-08-2019 - |
質問
ユーザーがサーバーに画像をアップロードできるようにするアプリケーションを作成しています。すべてのjpegで1日あたり約20枚の画像が表示され、おそらく編集/サイズ変更されません。 (これは別の質問です。保存する前にサーバー側で画像のサイズを変更する方法です。コメントなどで.NETリソースを削除してください)。 アップロードした画像を保存するのに最適な場所はどこかと思います。
-
画像をファイルシステムにファイルとして保存し、その画像への正確なパスを使用してテーブルにレコードを作成します。
-
または、<!> quot; image <!> quot;を使用して、画像自体をテーブルに保存します。または<!> quot; binary data <!> quot;データベースサーバーのデータ型。
両方に利点と欠点があります。 ファイルを簡単に再配置でき、テーブルエントリを変更するだけでよいため、a)が好きです。一方、ビジネスデータをWebサーバーに保存するのは好きではなく、Webサーバーをビジネスデータを保持する他のデータソースに接続したくない(セキュリティ上の理由から) b)が好きなのは、すべての情報が1つの場所にあり、クエリで簡単にアクセスできるためです。一方、データベースはすぐに非常に大きくなります。そのデータをアウトソーシングすることはより困難になる可能性があります。
解決
私は通常、ファイルシステムにファイルを保存します。例外がありますが、それがその目的のためです。ファイルの場合、ファイルシステムは最も柔軟でパフォーマンスの高いソリューションです(通常)。
データベースへのファイルの保存にはいくつかの問題があります-通常、ファイルは平均的な行よりもはるかに大きくなります-多くの大きなファイルを含む結果セットは多くのメモリを消費します。また、書き込みにテーブルロックを使用するストレージエンジン(ISAMなど)を使用する場合、保存するファイルのサイズ/レートによっては、ファイルテーブルが頻繁にロックされる場合があります。
セキュリティについて-通常、ファイルはドキュメントルートの外部のディレクトリ(httpリクエストからはアクセス不可)に保存し、最初に適切な承認をチェックするスクリプトを介して提供します。
他のヒント
オプションBの唯一の利点は、1つのシステムにすべてのデータがあることですが、それは誤った利点です!あなたのコードはデータの形式でもあり、データベースに保存することもできると主張するかもしれません。
固有のケースがない限り:
- ビジネスロジックはコードに属します。
- 構造化データはデータベースに属します(リレーショナルまたは非リレーショナル)。
- バルクデータはストレージ(ファイルシステムまたはその他)に属します。
ファイルを保持するためにファイルシステムを使用する必要はありません。代わりに、クラウドストレージ( Amazon S3 など)またはインフラストラクチャとしてのサービス(たとえば、 Uploadcare ):
https://uploadcare.com/upload-api-cloud-storage-and-cdn/
しかし、データベースにファイルを保存するのは悪い考えです。
Flickrはファイルシステムを使用します-こちら
クライアントは、いくつかの異なるバックエンドでオプションB(データベースストレージ)を何度か主張しましたが、最終的にはオプションA(ファイルシステムストレージ)に戻ってしまいました。
そのような大きなBLOBは、SQL Server 2005でも十分に処理されていません。SQLServer 2005は、私たちが試した最新のものです。
具体的には、深刻な肥大化が見られたため、ロックの問題があると思われます。
もう1つの注意:NTFSベースのストレージ(Windowsサーバーなど)を使用している場合、1つのディレクトリに何千ものファイルを配置する方法を見つけることを検討できます。理由はわかりませんが、ファイルシステムがその状況にうまく対応できない場合があります。誰かがこれについてもっと知っているなら、私はそれを聞きたいです。
しかし、私は常にサブディレクトリを使用して、少し物事を分割しようとします。多くの場合、作成日はこれに適しています:
Images / 2008/12/17 / .jpg
...これは適切なレベルの分離を提供し、デバッグ中にも少し役立ちます。本当に大きなディレクトリがある場合、エクスプローラーとFTPクライアントは同様に少し詰まることがあります。
編集: SQL Serverの最近のバージョンでは、2017年の簡単なメモに、多くのBLOBを処理するための新しいオプションがあります。
最近、MySQLテーブルにPDF / Wordファイルを保存するPHP / MySQLアプリを作成しました(これまでのファイルあたり最大40MB)。
長所:
- アップロードされたファイルは、他のすべてと一緒にバックアップサーバーに複製されます。個別のバックアップ戦略は必要ありません(安心)。
- Webサーバーのセットアップは、uploads /フォルダーがなく、すべてのアプリケーションにその場所を伝える必要がないため、少し簡単です。
- 編集にトランザクションを使用してデータの整合性を改善します-孤立したファイルや欠落しているファイルについて心配する必要はありません
短所:
- mysqldumpは、いずれかのテーブルに500MBのファイルデータがあるため、looooong時間かかります。
- ファイルシステムと比較した場合、全体的にあまりメモリ/ CPU効率的ではありません
実装を成功と呼びます。バックアップ要件を処理し、プロジェクトのレイアウトを簡素化します。アプリを使用する20〜30人のパフォーマンスは良好です。
これは古い投稿です。しかし、このページへの多くの訪問者は、質問に関連するものを何も得ていません。特に初心者向け。
ウェブサイトに画像やファイルをアップロードして保存する方法:
一部の共有ホスティングのファイルストレージはまだ十分なので、静的なWebサイトの場合はおそらく問題はありません。問題は、動的なWebサイトが大きくなると発生します。データベース内のより大きなものは処理できますが、画像などのファイル内のより大きなものは問題になります。ウェブサイトには2種類の画像があります:
-
画像は、動的ブログの管理者から提供されます。通常、これらの画像はアップロード前に最適化されています。
-
ユーザーの場合、ユーザーの画像はアバターなどの画像をアップロードできます。または、ユーザーはブログコンテンツを作成し、テキストエディターから画像を入力できます。この種の画像は、サイズを予測するのが困難です。ユーザーは、ビューサイズを変更することで小さなコンテンツだけに大きな画像をアップロードできますが、画像サイズは変更できません。
アイテム番号を無視することにより上記1、アイテム番号のクイックソリューション私たちのウェブサイトに画像オプティマイザー機能がない場合、2は次のヒントによって一時的に解決できます。
-
ユーザーが画像エディターにリダイレクトすることで、テキストエディターから直接アップロードできないようにします。このページでは、ユーザーはコンテンツに埋め込む前に事前にファイルをアップロードする必要があります。このメソッドは、ファイルマネージャーとして呼び出されます。
-
ユーザーが画像をアップロードするには、画像のトリミング機能を使用します。これにより、ユーザーが非常に大きなファイルをアップロードしても、画像サイズが制限されます。最終的な画像は、トリミングされた画像の結果です。サーバー側でサイズを定義し、たとえば500 KB以下のみを受け入れることができます。
今、それは一時的なものです。最終的な解決策として、質問が繰り返されます:
- 大きな画像のストレージを処理する方法は?
- 拡張子をサイズ変更または変更します。
- 大規模または中規模のWebサイトまたはeコマースが画像のファイルストレージを処理する方法
次にできること:
-
共有ホスティングVPSから移行します。十分ではない?その後、Dedicatedにアップグレードすることでさらに高くなります。
-
ファイルストレージ用に独自のサーバーを作成します。それを行うためにグーグル。これは思っているほど難しくありません。一部の人々は彼らのウェブサイトのためにそれをします。
-
簡単な方法は、CDNファイルストレージサービスを使用することです。
さて、1と2は少し高価です。しかし、最善の解決策だと思う3はありません。
一部のCDNサービスでは、必要な数のWebファイルを保存できます。
質問、<!> quot;当社のウェブサイトからCDNにファイルをアップロードする方法<!> quot;
心配する必要はありません。登録すると、通常は無料で、ファイルをアップロードし、Webサイトから/へのリンクを取得する方法のガイダンスが表示されます。 APIなどを取得します。それは簡単です。
一部のプロバイダーは、限られたストレージと帯域幅で14日間無料のサービスを提供しています。しかし、それは出発点としては大丈夫でしょう。唯一の問題は、「人々は決して試みない」ことです。
初心者に役立つことを願っています。
自分のウェブサイトでアップロードした画像を使用していますが、オプションa)と間違いなく言います。
もう1つお勧めするのは、ユーザーが写真に付けた名前からすぐにファイル名をより管理しやすい名前に変更することです。たとえば、各写真を一意に識別するための日付と時刻を含むもの。
また、将来の合併症を避けるために、ユーザーのファイル名から奇妙な文字を削除するのにも役立ちます。
画像のサイズを完全に変更し、可能であればその形式を確認します。たとえば、 GIFAR の脆弱性により、GIFファイル内の悪意のあるJavaアプレットを隠すことができ、現在のコンテキストでCookieを読み取り、クロスサイトスクリプティング攻撃のために別のサイトに送信できます。通常、画像のサイズを変更すると、埋め込みコードが変更されるため、これを防ぐことができます。この攻撃はJVMパッチによって修正されましたが、バイナリファイルをスクラブせずに単純に処理することにより、あらゆる種類の脆弱性が発生します。
ほとんどのウイルススキャナーはファイルシステムに対してのみ実行できます。バイナリをDBに保存すると、スキャナーを簡単に実行できなくなります。
ほとんどの実装はオプションAです。
オプションBを使用すると、データベースからこれらのビットをブラウザーに表示できるものにマーシャリングするときに、whoop4ssの大きな缶全体を開くことができます。また、dbがダウンしている場合、画像は使用できません。 / p>
スペースが問題になることはあまりないと思います...テラバイトドライブは数百ドルです。
オプションBを実行する時間またはリソースがないため、オプションAで実装しています。
自動サイズ変更には、imagemagickを試してください...多くの主要なオープンソースコンテンツ/写真管理システムに使用されています...そして、いくつかの.net拡張子があると思います。
SQL Server 2008には、 filestreamデータ型 RunAs Radio#74 。これは両方の世界の最高のようなものです。ほとんどの人は2008年のオプションを持っていませんが、あなたが持っている場合、このオプションはかなりクールに見えます
これは基本的に私です。
- アップロードした画像を一時ディレクトリまたはメモリに保存します。
- 画像を永続的に保存する前に処理します。 2.1。色補正 2.2。圧縮する 2.3。画像の寸法に基づいて複数のコピーを作成します 2.4。 .xl、.lg、.md、.smなどのサフィックスで名前を変更します
- すべての処理済み画像ファイル(単一ファイルから)を、フォルダー名が
id
のフォルダー内にパックします。これは、image file name
とともに任意の行/文書のデータベースに保存されます(または、画像名としてランダムな名前でもかまいません) 。 - yyyy / mm / d
path
フォルダーが存在しない場合は作成します。たとえば、2016/08/21。そのパスを覚えて、同じドキュメントと行のデータベースに保存します。 - 画像
/var/web-content/{{path}}/{{id}}/image-file-name.sm.jpg
フォルダーを<=>フォルダーに移動します。 (パスフォルダーは/ var / web-contentフォルダーにあります。) - メモリバッファをフラッシュするか、一時ファイルを削除します。
ドキュメントに記載されている画像にアクセスする必要がある場合、画像を含むフォルダのパスとIDがあります。たとえば、<=>
この方法では、処理されたすべての画像ファイルを削除する必要がある場合、フォルダーとそのコンテンツを再帰的に削除するだけです。
Aを使用します。共有ドライブに配置します(複数のサーバーを実行する予定がない場合)。
これがあなたのためにスケーリングしない時が来たら、キャッシュメカニズムを調査できます。
絶対に、肯定的にオプションA。他の人は、データベースがBLOBをうまく処理できないか、そうするように設計されているかどうかについて言及しています。一方、ファイルシステムはこのために生きています。 RAIDストライピングを使用して、複数のドライブにイメージを展開し、地理的に異なるサーバーにイメージを展開することもできます。
別の利点は、データベースのバックアップ/レプリケーションが巨大になることです。
オプションA。
画像が読み込まれたら、保存する前に形式を確認し、サイズを変更できます。 http://www.codeproject.com で画像のサイズを変更するための多数の.Netコードサンプルがあります。たとえば、 http://www.codeproject.com/KB/cs/Photo_Resize.aspx
セキュリティ上の理由から、 IEのコンテンツスニッフィングによる問題を回避することもベストプラクティスです。 により、攻撃者が画像ファイル内のJavaScriptをアップロードでき、サイトのコンテキストで実行される可能性があります。そのため、この種の攻撃を防ぐために、画像を保存する前に何らかの方法で画像を変換(トリミング/サイズ変更)することをお勧めします。 この回答には他にもアイデアがあります。
まあ、ユーザーがサーバーにファイルをアップロードする同様のプロジェクトがあります。私の観点では、オプションa)はより柔軟であるため、最適なソリューションです。あなたがしなければならないことは、サブディレクトリによって分類された保護されたフォルダに画像を保存することです。メインディレクトリーは管理者がセットアップする必要があります。コンテンツは、httpリクエストにアクセスできないようにスクリプトを実行(非常に重要)および(読み取り、書き込み)してはならないためです。
これがお役に立てば幸いです。
編集する必要のない小さなファイルであれば、オプションBは悪いオプションではありません。私は、ファイルを保存し、クレイジーなディレクトリ構造の問題に対処するロジックを記述するよりもこの方法を好みます。 1つのディレクトリに多くのファイルがあるのは悪いことです。よろしいですか?
ファイルが大きい場合、または特にofficeなどのプログラムからの継続的な編集が必要な場合は、オプションAが最適です。
ほとんどの場合、それは好みの問題ですが、オプションAを使用する場合は、ディレクトリに含まれるファイルが多すぎないようにしてください。オプションBを選択した場合、BLOBデータを含むテーブルを独自のデータベースまたはファイルグループ、あるいはその両方に作成します。これは、メンテナンス、特にバックアップ/復元に役立ちます。通常のデータはおそらくかなり小さいですが、画像データはやがて巨大になります。
要件、特にボリューム、ユーザー、検索の頻度によって異なります。ただし、小規模または中規模のオフィスの場合、Apple PhotosやAdobe Lighroomなどのアプリケーションを使用するのが最良の選択肢です。これらは、この種のリソースの保存、カタログ化、索引付け、および整理に特化しています。ただし、ストレージの要件が多く、ユーザー数が多い大規模な組織では、NuxeoやAlfrescoなどのデジタル資産管理を使用してコンテンツ管理プラットフォームをインスタンス化することをお勧めします。どちらも非常に優れたリソースを提供し、非常に大量のデータを簡単な方法で管理して取得します。そして、非常に重要です。両方のプラットフォームに無料の(オープンソース)オプションがあります。