web-dev-qa-db-ja.com

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

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

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

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

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

133
Tobias

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

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

セキュリティについて-私は通常、ドキュメントルートの外部のディレクトリ(httpリクエストではアクセスできない)にファイルを保存し、最初に適切な承認をチェックするスクリプトを介してファイルを提供します。

87
Eran Galperin

オプションBの唯一の利点は、1つのシステムにすべてのデータがあることですが、それは誤った利点です!あなたのコードはデータの形式でもあり、したがってデータベースに保存することもできると主張するかもしれません。

固有のケースがない限り:

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

Files, Code, Data

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

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

ただし、データベースにファイルを保存することはお勧めできません。

38

Flickrはファイルシステムを使用します-彼らは理由を議論します ここ

21
Martin Beckett

いくつかの異なるバックエンドでクライアントがオプションB(データベースストレージ)を数回主張し、alwaysがオプションA(ファイルシステムストレージ)最終的に。

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

具体的には、深刻な肥大化が見られたため、ロックの問題が発生していると思われます。

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

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

画像/2008/12/17/.jpg

...これにより、適切なレベルの分離が提供され、デバッグ時に少し役立ちます。エクスプローラーとFTPクライアントは、本当に巨大なディレクトリがある場合、少し詰まることがあります。

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

11
Brian MacKay

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

長所:

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

短所:

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

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

9
too much php

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

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

静的なWebサイトの場合、共有ホスティングのファイルストレージはまだ十分なので、問題はないでしょう。問題は、動的なWebサイトが大きくなると発生します。データベース内のより大きなものは処理できますが、画像などのファイル内のより大きなものは問題になります。 Webサイトには2種類の画像があります。

  1. 画像は、ダイナミックブログの管理者から提供されます。通常、これらの画像はアップロード前に最適化されています。

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

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

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

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

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

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

それでできること:

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

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

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

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

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

質問、「WebサイトからCDNにファイルをアップロードする方法」

通常は無料で登録すると、ファイルをアップロードし、Webサイトから/へのリンクを取得する方法についてのガイダンスが得られます。 APIなどを取得します。それは簡単です。

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

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

7
Sulung Nugroho

私は自分のウェブサイトでアップロードされた画像を使用しますが、オプションa)は間違いなく言うでしょう。

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

また、将来の合併症を避けるために、奇妙な文字のユーザーのファイル名を削除するのに役立ちます。

6
barfoon

画像のサイズを明確に変更し、可能であればその形式を確認します。悪意のあるファイルがアップロードされ、知らないホストによって処理されるケースがあります。たとえば、 GIFAR 脆弱性により、GIFファイル内の悪意のあるJavaアプレットを隠すことができます。その後、現在のコンテキストでCookieを読み取り、クロスサイトスクリプティング攻撃のために別のサイトに送信できます。通常、画像のサイズを変更すると、埋め込みコードが変更されるため、これを防ぐことができます。この攻撃はJVMパッチによって修正されましたが、バイナリファイルをスクラブせずに単純に処理することにより、あらゆる種類の脆弱性が発生します。

覚えておいてください、ほとんどのウイルススキャナーはファイルシステムに対してのみ実行できます。バイナリをDBに格納する場合、それらに対してスキャナーを非常に簡単に実行することはできません。

6
Tim Howland

これは基本的に私です。

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

文書に記載されている画像にアクセスする必要がある場合、画像を含むフォルダのパスとIDがあります。たとえば、/var/web-content/{{path}}/{{id}}/image-file-name.sm.jpg

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

3
Uday Hiwarale

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

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

スペースが問題になるとは思わない...テラバイトのドライブは今では数百ドルだ。

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

3
mson

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

3
jle

SQL Server 2008には、 filestream datatype と呼ばれるハイブリッドアプローチがあります。これは RunAs Radio#74 で説明されています。ほとんどの人は2008年のオプションを持っていませんが、あなたが持っている場合、このオプションはかなりクールに見えます

3
Charles Graham

オプションA.

画像をロードしたら、フォーマットを確認し、保存する前にサイズを変更できます。 http://www.codeproject.com で画像のサイズを変更するための多数の.Netコードサンプルがあります。例: http://www.codeproject.com/KB/cs/Photo_Resize.aspx

2
Leah

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

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

2
dj_segfault

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

2
Day

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

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

2
csexton

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

これがあなたのお役に立てば幸いです。

2
domoindal

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

1
Carlos Camargo

編集する必要のない小さなファイルであれば、オプションBは悪いオプションではありません。私は、ファイルを保存し、クレイジーなディレクトリ構造の問題に対処するロジックを記述するよりもこの方法を好みます。 1つのディレクトリに多くのファイルがあるのは悪いことです。いいですか?

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

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

1
Charles Graham