アップロードされた画像、SQLデータベース、ディスクファイルシステムを保存するのに最適な場所はどこですか?


146

ユーザーがサーバーに画像をアップロードできるアプリケーションを書いています。1日あたり約20枚の画像がすべてjpegであり、おそらく編集/サイズ変更されていないと思います。(これは別の質問です。保存する前にサーバー側で画像のサイズを変更する方法です。たぶん誰かが.NETリソースをコメントなどにドロップしてください)。アップロードした画像を保存するのに最適な場所は何でしょうか。

  • 画像をファイルシステムにファイルとして保存し、その画像への正確なパスを使用してテーブルにレコードを作成します。

  • または、データベースサーバーの「イメージ」または「バイナリデータ」データ型を使用して、イメージ自体をテーブルに格納します。

どちらにも長所と短所があります。私はa)が好きです。ファイルを簡単に再配置でき、テーブルエントリを変更する必要があるだけだからです。一方、ビジネスデータをWebサーバーに保存するのは好きではありません。また、Webサーバーをビジネスデータを保持する他のデータソースに接続したくありません(セキュリティ上の理由から)b)が好きなので、すべての情報は1つの場所にあり、クエリで簡単にアクセスできます。一方、データベースはすぐに非常に大きくなります。データのアウトソーシングはより困難になる可能性があります。


2
見つかりませんでした。どこですか?
Tobias


回答:


95

例外はありますが、通常はファイルシステムにファイルを保存します。ファイルの場合、ファイルシステムは(通常)最も柔軟でパフォーマンスの高いソリューションです。

データベースへのファイルの保存にはいくつかの問題があります-ファイルは一般的に平均行よりもはるかに大きいです-多くの大きなファイルを含む結果セットは多くのメモリを消費します。また、書き込みにテーブルロックを使用するストレージエンジン(ISAMなど)を使用する場合、ファイルテーブルは、そこに格納するファイルのサイズ/速度によっては、頻繁にロックされる可能性があります。

セキュリティに関して-私は通常、ファイルをドキュメントルートの外側(httpリクエストからはアクセスできません)の外にあるディレクトリに保存し、適切な認証を最初にチェックするスクリプトを通じてそれらを提供します。


7
最後の段落(セキュリティについて)について、技術的な詳細について説明していただけませんか。ありがとうございました。
VishwaKumar

39
(あなたがそこにいるすべてのグーグルのために)あなたのサイトのルートが(my_website /の代わりにmy_website / public /のように)「public」フォルダに設定されている場合、残りの画像とともにmy_website / my_imagesフォルダに画像を保存できますあなたのアプリ。次に、imgタグは「my_website / avatar.png」ではなく「my_website / image.php?img_id = 55」を参照します。image.phpスクリプトは、資格情報を確認し、渡したIDを解析した後、実際のIDを返します。画像。これにより、適切なログインユーザーのみが画像を表示できます。
キャプテンハイパーテキスト

8
キャプテンはそれを実際の回答に変えてポイントを獲得できるようにする必要があります$$$
Andrew

4
セキュリティ/ファイルがあなたのウェブサイトを破壊するのを防ぐことに関するいくつかのメモを追加してください
Andrew

1
これはスケーリングされません。フォルダー内のファイル数には制限があり、ファイルを複数のフォルダーに分割する場合は、ファイルのインデックス作成が複雑になります(ファイルが実際に格納されている場所を特定するため)。さらに、検索は非常に遅くなります。
Hardik 2018年

43

オプションBの唯一の利点は、1つのシステムにすべてのデータが含まれることですが、それは誤った利点です!コードもデータの一種であり、データベースにも格納できると主張するかもしれません。どのようにしますか?

特別なケースがない限り:

  • ビジネスロジックはコードに属します。
  • 構造化データはデータベースに属します(リレーショナルまたは非リレーショナル)。
  • バルクデータはストレージ(ファイルシステムまたはその他)に属します。

ファイル、コード、データ

ファイルを保持するためにファイルシステムを使用する必要はありません。代わりに、クラウドストレージ(Amazon S3など)またはその上にサービスとしてのインフラストラクチャ(Uploadcareなど)を使用できます。

https://uploadcare.com/upload-api-cloud-storage-and-cdn/

しかし、データベースにファイルを保存することは悪い考えです。



14

私はこれが古い記事であることを知っています。しかし、このページへの多くの訪問者は、質問に関連する何も得ていません。特に初心者のために。

ウェブサイトに画像やファイルをアップロードして保存する方法:

静的なWebサイトの場合、一部の共有ホスティング用のファイルストレージがまだ適切であるため、問題はない可能性があります。問題が大きくなるのは動的なWebサイトです。データベースの大きい方でも対応できますが、画像などのファイルの大きい方が問題になります。Webサイトには2種類の画像があります。

  1. 画像は動的ブログの管理者から取得されます。通常、これらの画像はアップロード前に最適化されています。

  2. ユーザーの場合のユーザーからの画像は、アバターなどの画像をアップロードできます。または、ユーザーはブログコンテンツを作成し、テキストエディターから画像を配置することもできます。この種の画像は、サイズを予測することが困難です。ユーザーは、ビューのサイズを変更することで小さなコンテンツの大きな画像をアップロードできますが、画像のサイズは変更できません。

アイテム番号を無視することによって。上記1、アイテム番号のクイックソリューション。2は、Webサイトにイメージオプティマイザー機能がない場合、次のヒントで一時的に解決できます。

  1. ユーザーが画像ギャラリーにリダイレクトして、テキストエディターから直接アップロードできないようにします。このページでは、コンテンツに埋め込む前に、ファイルを事前にアップロードする必要があります。このメソッドはファイルマネージャと呼ばれます。

  2. ユーザーが画像をアップロードするには、画像のトリミング機能を使用します。これにより、ユーザーが非常に大きなファイルをアップロードした場合でも、画像サイズが制限されます。最終的な画像は、トリミングされた画像の結果です。サーバー側でサイズを定義し、たとえば500Kb以下のみを受け入れることができます。

これは一時的なものです。最終的な解決策として、質問が繰り返されます:

  • 大きな画像ストレージをどのように処理しますか?
  • 拡張子をサイズ変更または変更します。
  • 大中規模のウェブサイトやeコマースは、画像のファイルストレージをどのように処理しますか?

私たちにできること:

  1. VPSをホストしている共有から移行します。十分ではない?次に、専用にアップグレードすることでさらに高くなります。

  2. ファイルストレージ用の独自のサーバーを作成します。それをするためにググる。これはあなたが考えるほど難しくはありません。一部の人々は彼らのウェブサイトのためにそれをします。

  3. 簡単な方法は、CDNファイルストレージサービスを使用することです。

さて、1と2は少し高価です。しかし、いいえ3は最良の解決策だと思います。

一部のCDNサービスでは、必要な数のWebファイルを保存できます。

「ウェブサイトからCDNにファイルをアップロードする方法は?」

登録すると、通常は無料で、心配はいりません。ファイルをアップロードし、Webサイトとの間でリンクを取得する方法のガイダンスが表示されます。APIなどを取得します。それは簡単です。

一部のプロバイダーは、ストレージと帯域幅が限られている14日間無料サービスを提供しています。しかし、それは出発点としては問題ありません。唯一の問題は、「人々は決して試みない」ということです。

それが初心者のために役立つことを願っています。


13

いくつかの異なるバックエンドでクライアントにオプションB(データベースストレージ)を数回要求してきました。要求してきましたが、最終的にオプションA(ファイルシステムストレージ)に戻ることになりました。

このような大きなBLOBは、SQL Server 2005でも十分に処理されていません。SQLServer 2005は、私たちが試した最新のものです。

具体的には、深刻な膨満感があり、おそらくロックの問題だと思います。

もう1つの注意:NTFSベースのストレージ(Windowsサーバーなど)を使用している場合は、1つのディレクトリに数千および数千のファイルを配置する方法を見つけることを検討してください。理由はわかりませんが、ファイルシステムがその状況にうまく対応できない場合があります。誰かがこれについてもっと知っているなら、私はそれを聞きたいです。

しかし、私は常にサブディレクトリを使用して、物事を少し分解するようにしています。多くの場合、作成日はこれに適しています。

画像/2008/12/17/.jpg

...これはまともなレベルの分離を提供し、デバッグ中にも少し役立ちます。本当に巨大なディレクトリがある場合、エクスプローラーとFTPクライアントは同様に少し窒息する可能性があります。

編集: 2017年の簡単なメモ、SQL Serverの最近のバージョンでは、先ほど説明した欠点を回避するために多数のBLOBを処理するための新しいオプションがあります。

編集: 2020年のクイックノート、AWS / AzureなどのBlob Storageも長年オプションになっています。これは安価であり、多くの場合、展開、複数のサーバーへのスケーリング、必要に応じて他の環境のデバッグなどに関する特定の問題を単純化できるため、多くのWebベースのプロジェクトに最適です。


4
同じディレクトリにあるファイルの数に関する警告。本番環境では見つけるのが難しいエラーが発生する可能性があります。
digao_mb 2014

1
以前にこの問題に遭遇したことがあります。NTFSは、フォルダー内に約10,000個のファイルがあると予期せず動作しました。
Faiz

1
NTFSだけでなく、BTRFSも1つのフォルダー内の大量の画像を処理する際に問題があります。つまり、それをしようとするlsと永遠にかかります(ハング)。または削除します。
sunapi386

11

最近、PDF / WordファイルをMySQLテーブルに保存するPHP / MySQLアプリを作成しました(これまでのところ、ファイルあたり最大40MB)。

長所:

  • アップロードされたファイルは、他のすべてと一緒にバックアップサーバーに複製されます。個別のバックアップ戦略は必要ありません(安心)。
  • uploads /フォルダーを用意してすべてのアプリケーションにその場所を知らせる必要がないため、Webサーバーの設定は少し簡単です。
  • データの整合性を向上させるために編集にトランザクションを使用できます-孤立したファイルや欠落しているファイルについて心配する必要はありません

短所:

  • mysqldumpは、テーブルの1つに500MBのファイルデータがあるため、非常に時間がかかります。
  • ファイルシステムと比較した場合、全体的にメモリ/ CPU効率はそれほど高くありません

私は自分の実装を成功と呼び、バックアップ要件を処理し、プロジェクトのレイアウトを簡素化します。アプリを使用する20〜30人にとってパフォーマンスは良好です。


6

私は自分のウェブサイトでアップロードされた画像を使用しています。

私が強くお勧めするもう1つのことは、ファイル名をユーザーが写真に付けた名前からすぐに管理しやすいものにすぐに変更することです。たとえば、各画像を一意に識別するための日付と時刻を含むもの。

また、将来の複雑化を回避するために、ユーザーのファイル名にある奇妙な文字を取り除くのにも役立ちます。


6

画像のサイズを確実に変更し、可能であればフォーマットを確認してください。悪質なファイルのがありました場合は、アップロードして、例えばhosts-無意識によって提供されてGIFAR脆弱性は、現在のコンテキストでクッキーを読み、それらを送ることができるでしょうこれ、あなたがGIFファイルに悪質なJavaアプレットを非表示にする許可しましたクロスサイトスクリプティング攻撃の別のサイト。画像のサイズを変更すると、埋め込みコードが変更されるため、通常はこれを防ぎます。この攻撃はJVMパッチによって修正されていますが、バイナリファイルをスクラブせずに単純に提供することで、あらゆる範囲の脆弱性に遭遇します。

ほとんどのウイルススキャナーはファイルシステムに対してのみ実行できることに注意してください。バイナリをDBに保存すると、それらに対してスキャナーを簡単に実行することができなくなります。


4

SQL Server 2008には、RunAs Radio#74で話題になっているfilestreamデータ型と呼ばれるハイブリッドアプローチがあり、これは両方の世界で最も優れているようなものです。ほとんどの人は2008年のオションを持っていませんが、持っている場合、このオプションはかなりクールに見えます


4

これは基本的にそうです。

  1. アップロードした画像を一時ディレクトリまたはメモリに保存します。
  2. そのイメージを永続的に保存する前に処理します。2.1。色補正2.2。2.3を圧縮します。画像の寸法に基づいていくつかのコピーを作成します2.4。.xl、.lg、.md、.smなどのサフィックスを使用して名前を変更します。
  3. すべてのid行/ドキュメントと共にデータベースに保存されるフォルダー名のフォルダー内に、(単一のファイルから)処理されたすべての画像ファイルをパックしますimage file name(または画像名としてランダムな名前の可能性がある。
  4. yyyy / mm / dを作成 pathフォルダーが存在しない場合は。たとえば2016/08/21。そのパスを覚えて、同じドキュメントと行のデータベースに保存します。
  5. 画像idフォルダをに移動pathフォルダにます。(パスフォルダーは/ var / web-contentフォルダーにあります。)
  6. メモリバッファをフラッシュするか、一時ファイルを削除します。

ドキュメントで言及されている画像にアクセスする必要がある場合は、画像が含まれているフォルダのパスとIDがあります。例えば/var/web-content/{{path}}/{{id}}/image-file-name.sm.jpg

この方法で、処理済みのすべての画像ファイルを削除する必要がある場合は、フォルダーとそのコンテンツを再帰的に削除するだけです。


3

ほとんどの実装はオプションAです。

オプションBを使用すると、データベースからこれらのビットをブラウザーで表示できるものにマーシャリングするときに、whoop4ssの大きな缶を開くことができます。また、dbがダウンしている場合、イメージは利用できません。

スペースが問題になりすぎるとは思いません...テラバイトのドライブは現在数百ドルです。

オプションBを実行する時間やリソースがないため、オプションAを使用して実装しています。


3

自動サイズ変更については、imagemagickを試してください。多くの主要なオープンソースコンテンツ/写真管理システムで使用されています。また、.net拡張子がいくつかあると思います。


2

Aを使用します。共有ドライブに配置します(複数のサーバーを実行する予定がない場合を除く)。

これがスケーリングされない時が来たら、キャッシュメカニズムを調査できます。


2

確かに、肯定的なオプションAです。他の人たちは、データベースがBLOBを扱うように設計されているかどうかにかかわらず、一般にBLOBをうまく処理しないと述べています。一方、ファイルシステムはこれに対応しています。RAIDストライピングを使用したり、複数のドライブにイメージを分散したり、地理的に離れたサーバーにイメージを分散したりすることもできます。

もう1つの利点は、データベースのバックアップ/レプリケーションが巨大になることです。



2

セキュリティ上の理由から、IEのコンテンツスニッフィングによって引き起こされる問題を回避することもベストプラクティスです。これにより、攻撃者が画像ファイル内のJavaScriptをアップロードし、サイトのコンテキストで実行される可能性があります。したがって、この種の攻撃を防ぐために、画像を保存する前に何らかの方法で画像を変換(トリミング/サイズ変更)することができます。この回答には他にもいくつかのアイデアがあります。


2

まあ、私はユーザーがサーバーにファイルをアップロードする同様のプロジェクトを持っています。私の見解では、オプションa)はより柔軟であるため、最良のソリューションです。あなたがしなければならないことは、サブディレクトリによって分類された保護されたフォルダに画像を保存することです。コンテンツはスクリプトを実行してはならず(非常に重要)、(読み取り、書き込み)HTTPリクエストでアクセスできないように保護されているため、メインディレクトリは管理者が設定する必要があります。

これがお役に立てば幸いです。


1

編集する必要がない小さなファイルの場合、オプションBは悪いオプションではありません。私はこれを、ファイルを格納し、クレイジーなディレクトリ構造の問題に対処するロジックを書くよりも好みます。持つたくさんの一つのディレクトリ内のファイルのことは悪いです。大丈夫?

ファイルが大きい場合、または特にOfficeなどのプログラムからの継続的な編集が必要な場合は、オプションAが最適です。

ほとんどの場合、それは好みの問題ですが、オプションAを実行する場合は、ディレクトリのファイルが多すぎないようにしてください。オプションBを選択した場合は、BLOB化されたデータを含むテーブルを独自のデータベースまたはファイルグループ、あるいはその両方に配置します。これは、メンテナンス、特にバックアップ/復元に役立ちます。通常のデータはかなり小さいですが、画像データは時間の経過とともに膨大になります。


1

これは、要件、特にボリューム、ユーザー、および検索の頻度によって異なります。ただし、中小規模のオフィスでは、Apple PhotosやAdobe Lighroomなどのアプリケーションを使用するのが最善の方法です。これらは、この種のリソースの保管、カタログ、索引付け、および整理に特化しています。ただし、大規模な組織では、ストレージ要件が高く、ユーザー数が多いため、NuxeoやAlfrescoなどのデジタル資産管理を使用してコンテンツ管理プラットフォームをインスタンス化することをお勧めします。どちらも非常に優れたリソースを提供しており、それらを取得するための簡略化された方法で大量のデータを管理します。そして、非常に重要です。両方のプラットフォームに無料の(オープンソース)オプションがあります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.