ユーザーがアップロードした写真を処理し、それらをデータベースとサーバーに保存するための通常のプラクティスは何ですか?
ユーザープロフィール画像の場合:
<image_id>_<username>
に変更します/images/userprofile
に移動しますfirst_name, last_name, age, gender, birthday
などのプロファイルの詳細を含むusers
テーブルにimgファイル名を追加しますユーザーが行ったレビュー用の画像の場合:
<image_id>_<review_id>
に変更します/images/reviews
に移動しますreview_id, review_content, user_id, score
などのプロファイルの詳細を含むreviews
テーブルにimgファイル名を追加します。質問1:ユーザーが特定のレビュー用に複数の写真をアップロードできる場合、画像ファイル名を保存するにはどうすればよいですか?シリアライズ?
質問2:または、画像を追跡するためだけに別のテーブルreview_images
カラムreview_id, image_id, image_filename
がありますか?このテーブルからimage_filename
を取得するときにJOIN
を実行すると、パフォーマンスが著しく低下しますか?
質問:すべての画像を単一のフォルダーに保存する必要がありますか?同じフォルダに10万枚の写真がある場合、問題が発生しますか?
これを行うためのより効率的な方法はありますか?
簡単な答え:画像ファイル名をデータベースに保存する必要はありません。アップロードするファイルの名前をtheirusername.jpg
に変更し、/uploads/users/
に保存するだけです。以下の長い回答。
質問1:ユーザーが特定のレビュー用に複数の写真をアップロードできる場合、画像ファイル名を保存するにはどうすればよいですか?シリアライズ?
あなたは出来る:
ファイル名をカンマ区切りにして、images
テーブルの単一のreview
フィールドに保存します。表示する画像を取得する場合、images
文字列をカンマで分割し、その配列をループして画像をレイアウトします。 (画像が1つしかない場合でも、これは機能します。)
2番目の質問で提案するように、images
またはreview_images
という名前の個別のテーブルを作成し、各画像を独自の行に保存します。
質問2:または、画像を追跡するためだけに、review_id、image_id、image_filenameの列を持つ別のテーブルreview_imagesがありますか?このテーブルからimage_filenameを取得するときにJOINを実行すると、パフォーマンスが著しく低下しますか?
単純なJOINを使用しても、パフォーマンスが著しく低下することはほとんどありません。クエリをキャッシュし、静的なHTMLを提供することにより、パフォーマンスの小さなヒットを無効化または削減できます。
質問3:すべての画像を単一のフォルダーに保存する必要がありますか?
次のいずれかをお勧めします。
/uploads/
ディレクトリにユーザーごとに1つのフォルダーを作成します。これにより、ファイル数のディレクトリ制限に達する可能性が減少します。
同じフォルダに10万枚の写真がある場合、問題が発生しますか?
おそらく、サーバーが使用するファイルシステムによって異なります。 1つのディレクトリに含めることができるファイルの数には制限があります。たとえば、FAT32には、フォルダーあたり65,535ファイルの制限があります。 Stack Overflowの "ディレクトリ内のファイルが多すぎますか?" を参照してください。上記で提案したようにフォルダを使用すると、ディレクトリの制限に達する危険性が減ることに注意してください。
これを行うためのより効率的な方法はありますか?
単純な規則に従う場合、データベースに画像データを保存する必要はまったくありません。たとえば、ユーザーがプロファイル画像をアップロードする場合、その名前をprofile.jpg
に変更し、/uploads/users/username/
に保存できます。これで、プロフィール画像を取得するためにユーザーのユーザー名のみが必要になります。データベースへの画像への参照を保存する必要はもうありません。 (または、イメージにtheirusername.jpg
という名前を付けて/uploads/users/
に保存するだけで、あなたにとって意味のある規則を選択できます。)
同様に、ユーザーがレビュー用の画像をアップロードする場合、/uploads/reviews/13/
というフォルダーにそれらの画像を保存できます。末尾の13番はレビューIDです。これは、データベーステーブルに保存されているそのレビューの一意のIDです。これらの画像を表示するには、それらの画像を取得するために必要なのはレビューIDだけです。 (フォルダ内の画像を調べるには、ディレクトリをスキャンします。PHPでは、たとえば scandir() を使用します。)
データベースに関するイメージに関する情報(ユーザー名、イメージID、ファイル名)を保存し、JOINでこれを取得します。
Stack Overflowのこのスレッド は同じアイデアを説明していますが、参照したい正確なスレッドが見つからなかったため、より良い説明が得られます。 Michael Andrewsが 彼のブログ でこのようなスキームを実装する方法の実際の実践について説明しています...
基本的な考え方は、画像の内容をハッシュし、そのハッシュをファイル名として使用して画像を保存することです。
複数の人が同じ画像をアップロードする場合、サーバーに保存されるのは一度だけです。データベースにそのファイル名への参照がなくなったら、いつでも削除できます。