web-dev-qa-db-ja.com

画像用に別のテーブルを作成するか、または「画像フィールド」を多くのテーブルに追加しますか?

複数のテーブルに画像があるデータベースを作成する必要があります。

たとえば、ユーザーにはプロフィール写真とアップロードされた写真があり、製品には多くの写真もあります。

MySqlテーブルを1つ「イメージ」にするか、それを含むすべてのテーブルに「イメージ」を追加するほうが良いですか。

また、多くの画像をMySqlデータ列にどのように追加しますか(構文の質問はここには含まれませんが、それはいいでしょう)。

ファイルパスと実際のファイルをデータベースに保存することの利点について読みましたが、ファイルパスが多く、行数が多い長い文字列はどうなりますか?

例えば

INSERT INTO images (userid, image1, image2, image3) 
VALUES (autoincrementedPK 'pathtofile1', 'pathtofile2', 'pathtofile3') 

または

INSERT INTO images (userid, images) 
VALUES (autoincrementedPK, 'pathtofile1, pathtofile2, pathtofileN')

どのオプションがより良いのか、そしてその理由は?オプション2は実行可能ですか?もしそうなら、それをどのように実装しますか?

5
octohedron

まずファイルパスの保存について:

  • 複数の画像パス列(imagepath1、imagepath2 ... imagepathN)があると、 1NFに違反します。
  • 同じ列に複数のコンマ区切りの画像パスを格​​納することも1NFに違反します。
  • 最も単純な通常の形式に違反すると、将来、多くの頭痛の種になるでしょう。
  • 正しいことは画像用に別のテーブルを作成することです。そのテーブルには、ユーザーテーブル(userid)を持つFKがあります。次に、特定のユーザーに必要な数の画像パスをそのテーブルに挿入します。

実際の画像の保存について [〜#〜] blobs [〜#〜]

  • NF1について同じルールが適用されます。画像には同じ別の表が適用されます。
  • この場合、DBAはイメージテーブルを個別のテーブルスペースに配置し、ディスクを最適化して [〜#〜] io [〜#〜] にすることができるため、BLOBSに個別のテーブルを配置するのが適切です。
  • ユーザーが1つの画像しか許可されていない場合でも、1対1の関係を持つ個別のテーブルを作成して非正規化することをお勧めします。

注:MySQLのデータ型に慣れていないため、構文を説明することはできません。

4

私はファイルパスの問題について ser61852 に全面的に同意しますが、BLOBSについては十分に反対することはできません。

この質問では、それがWebアプリケーションであるか、より伝統的なクライアント/サーバーアプリケーションであるかについて具体的に言及していませんが、ユーザーと製品について提供されているコンテキストからWebアプリについて話しているようです。

その場合、特に www.cloudflare.com のような驚くべき無料の透明CDNを使用する場合、CDNを使用しないことの言い訳はありません。他にもありますが、私はCloudFlareが大好きで、あまりお勧めできません。 CDNを使用することは、特定のCDNを使用するよりも重要だと思います...

ファイルを最適化するために非常に低いレベルで調整できる専用のハードウェアがない限り、BLOBとしてDBにイメージを保存することは、ファイルシステムよりも実際には高速ではありませんIO(そして専門家がほとんどいないOS /ドライバーレベルでこの問題に取り組んでいる何千人ものエンジニアよりも実際にこれを上手に実行している人に出会いました。

さらに悪いことに、DB BLOBSを使用することで、静的画像(およびCSS、JS、フォント...)アセットを地理的に分散してホストするという信じられないほど高速なCDNオプションをWeb訪問者のできるだけ近くで排除できるだけでなく、 nginxなどの高速WebサーバーやVarnishなどのフロントエンドキャッシュシステムを使用して画像(およびCSS、JSなど)を提供するオプションを放棄することは、Apacheおよび=よりも高速であるため、残念です。 IIS正しく構成されている場合。

当然、アセットがファイルシステムに保存されていない限り、個々のコンポーネントを使用できないため、nginx、varnish、およびCDNを組み合わせるオプションも放棄します。

クラスター化されたクラウド環境にデプロイされるアプリをいくつか開発しましたが、クラスター内のすべてのサーバーに必要なファイルアセットを配布するという課題がありました。最初は、画像アセットをBLOBとしてDBに保存することを検討したくなるかもしれません。そうすることで、すべてのノードがそれらにアクセスでき、それらのアセットのデプロイについて心配する必要がなくなります...

この誘惑を避けてください。私は、ファイルシステム、Webサーバー、キャッシュ、およびCDNに最適な機能を実行させ、DBに最適な機能を実行させる方が良いことを発見しました。そして、それは間違いなく画像を保存してWebアプリケーションにすばやく提供することではありません。