web-dev-qa-db-ja.com

すべきこと、すべきでないこと:画像をデータベースに保存する

Webアプリケーションのコンテキストでは、私の古い上司は常に、画像自体ではなく画像への参照をデータベースに置くと言っていました。私は、URLと画像自体をDBに保存することをお勧めしますが、現在作業している場所では、データベースに多くの画像を保存しています。

私が考えることができる唯一の理由は、おそらくそれがより安全であることでしょうか?あなたは誰かがURLへの直接リンクを持ちたくないのですか?ただし、その場合は、asp.netのハンドラーのように、常にWebサイト/サーバーで画像を処理できるため、ユーザーは画像を表示するために認証を受ける必要があります。また、データベースから画像を引き出すことでパフォーマンスが低下することも考えています。画像をデータベースに保存することが良い/あまり良い考えではない他の理由はありますか?


正確な複製:ユーザー画像:データベースまたはファイルシステムのストレージ?
正確な複製:データベースへの画像の保存:はいまたはいいえ?
正確な重複:画像をデータベースまたはフォルダに保存する必要がありますか?
正確な重複:バイナリデータをデータベースまたはフォルダに保存しますか?
完全な複製:画像をファイルとして保存するか、またはWebアプリのデータベースとして保存しますか?
正確な重複:少数の画像の保存:blobまたはfs?
完全な重複:画像をファイルシステムまたはデータベースに保存しますか?

30
nickytonline

場合によって画像を取得する必要があり、複数の異なるWebサーバーで使用できる必要がある場合。しかし、私はそれでほとんどだと思います。

  • 複数のサーバーで使用できる必要がない場合は、常にファイルシステムに配置することをお勧めします。
  • 複数のサーバーで使用できるようにする必要があり、実際にシステムになんらかの負荷がある場合は、何らかの分散ストレージが必要になります。

ここではEdgeのケースについて説明します。この場合、データベースを活用することで、システムに複雑さを追加することを回避できます。

それ以外はしないでください。

21
Emil H

画像をデータベースに入れる長所。

  1. トランザクション。 BLOBを保存すると、他のDBデータと同様にコミットできます。つまり、関連するメタデータと一緒にblobをコミットし、2つが同期していることを確認できます。ディスク容量が足りなくなったら?コミットなし。ファイルが完全にアップロードされませんでしたか?コミットなし。愚かなアプリケーションエラー?コミットなし。画像とそれらに関連付けられたメタデータを互いに整合させることがアプリケーションにとって重要である場合、DBが提供できるトランザクションは恩恵になる可能性があります。

  2. 管理する1つのシステム。メタデータとブロブをバックアップする必要がありますか?データベースをバックアップします。それらを複製する必要がありますか?データベースを複製します。部分的なシステム障害から回復する必要がありますか? DBをリロードし、ログをロールフォワードします。 DBが一般にデータにもたらすすべての利点(ボリュームマッピング、ストレージ管理、バックアップ、レプリケーション、リカバリなど)は、BLOBに適用されます。一貫性が向上し、管理が容易になります。

  3. セキュリティ。データベースには、活用できる非常に細かいセキュリティ機能があります。スキーマ、ユーザーロール、さらには「読み取り専用ビュー」などでも、データのサブセットに安全にアクセスできます。これらの機能はすべて、BLOBを保持するテーブルでも機能します。

  4. 集中管理。 #2に関連していますが、基本的にDBAは(十分なパワーがないかのように)1つのこと、つまりデータベースを管理します。最近のデータベース(特に大きなデータベース)は、複数のマシンにまたがる大規模なインストールで非常にうまく機能します。管理の単一のソースは、手順を簡素化し、知識の伝達を簡素化します。

  5. 最近のほとんどのデータベースは、ブロブを問題なく処理します。データ層でのBLOBのファーストクラスサポートにより、DBからクライアントにBLOBを簡単にストリーミングできます。一度にすべてのblobを「吸い込む」ことができる操作がありますが、その機能が不要な場合は使用しないでください。 DBのSQLインターフェイスを調べ、その機能を活用します。それらをモノリシックに扱われる「大きな文字列」のように扱い、ブロブを大きなメモリのガブリング、キャッシュスマッシング爆弾に変える理由はありません。

  6. 画像専用のファイルサーバーを設定できるのと同じように、データベースに専用BLOBサーバーを設定できます。専用のディスクボリューム、専用のスキーマ、専用のキャッシュなどを提供します。DB内のすべてのデータが同じではない、または同じように動作する、すべてを同じように構成する理由はありません。優れたデータベースは細かいレベルで制御できます。

DBからBLOBを提供することに関する主な目的は、HTTPレイヤーが実際にすべてのHTTPプロトコルを利用してサービスを実行することを保証することです。

多くの単純な実装は、単にblobを取得し、ソケットに大量にダンプします。ただし、HTTPには、ストリーミング画像などに適した重要な機能がいくつかあります。特に、ヘッダー、ETag、チャンク転送をキャッシュして、クライアントがblobの「ピース」をリクエストできるようにします。

HTTPサービスがこれらのすべてのリクエストを適切に受け入れていることを確認してください。DBは非常に優れたWebシチズンになることができます。 HTTPサーバーで提供するためにファイルシステムにファイルをキャッシュすることで、「無料」でこれらの利点のいくつかを得ることができます(優れたサーバーは「静的」リソースに対してとにかくそれを行うので)、しかし、それを行う場合は、画像の変更日などを尊重します。

たとえば、誰かが2009年1月1日に作成された画像であるspaceshuttle.jpgをリクエストします。これは、リクエスト日、たとえば2009年2月1日にファイルシステムにキャッシュされます。その後、イメージはキャッシュから削除されます(FIFOポリシー、または何でも)、そして誰かが後で2009年3月1日に再度要求しました。ええと、2009年3月1日の「作成日」は、作成日が実際には1月1日であったとしても、このようになりました。特に、キャッシュが頻繁に回転する場合は、If-を使用している可能性があるクライアントを確認できます。変更されたヘッダーは、実際には変更されていないのにサーバーがリソースが変更されたと考えているため、実際に必要とするよりも多くのデータを取得している可能性があります。

キャッシュの作成日を実際の作成日と同期させておくと、問題が少なくなる可能性があります。

しかし、要点は、問題全体を「良いWeb市民」にして、あなたとあなたのクライアントに潜在的にある程度の帯域幅などを節約するために熟考することです。

私はJava DBからビデオを提供するプロジェクトのためにこれをすべて試してみました、そしてそれはすべて御馳走として機能します。

49
Will Hartung

データベースに画像を保存する(または言及する)と、データベースの専門家の大多数があなたの指とヒスを交差させることを理解しています。はい、データベースをあらゆる種類のバイナリデータの大きなブロックのリポジトリとして使用する場合、パフォーマンスとストレージに明確な影響があります(画像は、正規化できない最も一般的なデータビットになりがちです)。ただし、画像のデータベースストレージが許可されるだけでなく、推奨である状況が最も確実に存在します。

たとえば、私の古い仕事では、ユーザーが書いているレポートのいくつかの異なるポイントにユーザーが画像を添付するアプリケーションがあり、それらの画像は完了時に印刷する必要がありました。これらのレポートはSQL Serverレプリケーションを介して移動され、これらのイメージとファイルパスを複数のシステムとサーバー間であらゆる種類の信頼性をもって管理しようとすると、大きな頭痛の種になります。それらをデータベースに保存すると、すべてが「無料」で提供され、レポートツールは画像を取得するためにファイルシステムに出向く必要がなくなりました。

13
Adam Robinson

私の一般的なアドバイスは、自分を1つのアプローチに限定することではなく、状況に適した手法を使用することです。ファイルシステムはファイルの保存に優れており、データベースは要求に応じて一口サイズのデータ​​のチャンクを提供するのに優れています。一方、私の会社の製品の1つでは、アプリケーションの状態全体をデータベースに格納する必要があります。つまり、添付ファイルもそこに格納されます。私たちのDBサーバー(SQL Server 2005)では、大規模な顧客やデータベースを使用した場合でも、まだ観測可能なパフォーマンスの問題に遭遇していません。

MicrosoftのSQL 2008は、FileStream機能で両方の長所を提供します。チェックする価値があるかもしれません。 http://technet.Microsoft.com/en-us/library/bb933993.aspx

8
James Orr

画像をデータベースに保存することの利点の1つは、システム間で移植可能であり、ファイルシステムのレイアウトに依存しないことです。

7
Thevs

最も単純で、最もパフォーマンスが高く、最もスケーラブルなソリューションは、イメージをファイルシステムに保存することです。セキュリティが懸念される場合は、Webサーバーからアクセスできない場所にそれらを置き、セキュリティを処理してファイルを提供するスクリプトを記述します。

Web /アプリサーバーとDBサーバーが異なるマシンであると想定すると、DBに画像を配置することで、数回のヒットが発生します:(1)2つのマシン間のネットワーク遅延、(2)DB接続オーバーヘッド、(3)追加のDBの消費提供される各画像の接続最後の点についてもっと心配します。サイトが多くの画像を提供している場合、Webサーバーは多くのDB接続を消費し、接続プールを使い果たす可能性があります。

6
cliff.meyers

アプリケーションが複数のサーバーで実行されている場合は、画像の参照コピーをデータベースに保存し、必要に応じてファイルシステムにキャッシュします。そうすることは、ファイルシステムを横方向に同期することを試みるよりも、お尻のエラーが発生しやすい痛みよりもはるかに少ないです。

アプリケーションが単一のサーバー上にある場合は、ええ、ファイルシステムに固執し、データベースにデータへのパスを維持させます。

5
chaos

もちろん、ほとんどのSQLデータベースは画像を提供することを念頭に置いて設計されていませんが、データベースに画像を配置することにはある程度の利便性があります。

たとえば、すでにデータベースが実行されており、レプリケーションが構成されている場合です。 rsyncまたはnfsベースのファイルシステムレプリケーションを実行するのではなく、すぐにHAイメージストアを使用できます。また、ファイルをディスクに書き込むための一連のWebプロセス(またはいくつかの新しいサービスの設計)があると、複雑さが少し増加します。本当にそれはただもっと動く部分です。

少なくとも、画像に関する「メタ」データ(権限、所有者など)と実際のデータを別のテーブルに分けておくことをお勧めします。そうすれば、別のデータストアに簡単に切り替えることができます。この線。これを何らかのCDNまたはキャッシングと組み合わせると、ある程度まではかなり良好なパフォーマンスが得られるはずです。そのため、このアプリケーションのスケーラビリティと、実装の容易さのバランスをどのように取るかによって異なります。

3
rhettg

URLを保存する必要はありません(これが安全でないと思われる場合)。他の場所で画像を参照する一意のIDを保存するだけです。

データベースストレージは、ファイルシステムよりも高価で維持コストがかかる傾向があるため、データベースに大量の画像を保存することはしません。

2
Fortyrunner

定期的にデータベースから取り出される画像の場合、私は常にファイルシステムを使用しようとします。

たまに引き出す必要のある画像で、データベースに保存しておくと楽になりますが、何の問題もありません。

1
user31571

デモアプリケーション用にデータベースに画像を保存しました。私がそれをした理由はセキュリティでした-必要のないレコードを削除することは大きな問題ではありませんでしたが、必要のないファイルを削除することは問題だったのかもしれません!

パフォーマンスが問題になった場合、不正なファイルの削除が実際に可能かどうかを調査しました。

1
Andrew Grimm

データベースにテラバイトの画像データが保存されている場合、災害復旧はまったく面白くありません。データをより信頼性の高いものにするためのより良い方法を見つけた方がいいでしょう...もちろん、複製するときなど、すべてのオーバーヘッド(前述)が倍増します...

やらないで!

1
Richard

これは本当にKISS(単純に愚かにしておく)問題のようです。ファイルシステムは画像ファイルの保存を簡単に処理できるように作られていますが、データベースで行うのは簡単ではなく、データ。ファイルのセキュリティについて心配するだけでよいのに、パフォーマンスヒットとsqlとレンダリングのすべての困難を伴うのはなぜですか?NFSまたはCIFSを使用した混合システムも処理できます。ファイルシステムは成熟したテクノロジです。はるかにシンプルで堅牢です。

1
Dan Littlejohn