Quelle est la pratique habituelle pour gérer les photos téléchargées par l’utilisateur et les stocker dans la base de données et le serveur?
Pour une image de profil utilisateur:
<image_id>_<username>
/images/userprofile
users
contenant les détails de leur profil, comme first_name, last_name, age, gender, birthday
Pour une image pour une révision faite par l'utilisateur:
<image_id>_<review_id>
/images/reviews
reviews
contenant les détails de leur profil, comme review_id, review_content, user_id, score
.Question 1: Comment dois-je procéder pour stocker les noms de fichiers d'images si l'utilisateur peut télécharger plusieurs photos pour un commentaire particulier? Sérialiser?
Question 2: Ou avez-vous une autre table review_images
avec des colonnes review_id, image_id, image_filename
uniquement pour le suivi des images? Est-ce que faire un JOIN
lors du rappel du image_filename
de ce tableau ralentira sensiblement les performances?
Question: Toutes les images doivent-elles être stockées dans un seul dossier? Y aura-t-il un problème lorsque nous aurons 100 000 photos dans le même dossier?
Existe-t-il un moyen plus efficace de procéder?
Réponse courte: inutile de stocker le nom de fichier de l'image dans la base de données. Il suffit de renommer le fichier téléchargé en theirusername.jpg
et de le stocker dans /uploads/users/
. Réponse plus longue ci-dessous.
Question 1: Comment dois-je procéder pour stocker les noms de fichiers d'images si l'utilisateur peut télécharger plusieurs photos pour un commentaire particulier? Sérialiser?
Vous pourriez:
Séparez les noms de fichiers par une virgule et stockez-les dans un seul champ images
dans la table review
. Lorsque vous récupérez des images à afficher, scindez la chaîne images
par une virgule et passez en boucle sur ce tableau pour les disposer. (S'il n'y a qu'une seule image, cela fonctionnera toujours.)
Créez une table séparée appelée images
ou review_images
et stockez chaque image sur sa propre ligne, comme vous le suggérez dans votre deuxième question.
Question 2: Ou avez-vous une autre table review_images avec des colonnes review_id, image_id, image_filename uniquement pour le suivi des images? Le fait de faire une jointure lors de la récupération du nom de fichier image de cette table ralentira-t-il sensiblement les performances?
Il est peu probable que vous perceviez des difficultés de performance en utilisant un simple JOIN. Vous pouvez nier ou réduire vos petits succès en termes de performances en mettant en cache des requêtes et en servant du code HTML statique.
Question 3: Toutes les images doivent-elles être stockées dans un seul dossier?
Je vous suggérerais soit:
/uploads/
lors du téléchargement de son premier fichier.Cela réduit les risques de limite de répertoires sur le nombre de fichiers.
Y aura-t-il un problème lorsque nous aurons 100 000 photos dans le même dossier?
Peut-être, en fonction du système de fichiers utilisé par votre serveur. Il y a des limites au nombre de fichiers que vous pouvez avoir dans un seul répertoire. FAT32, par exemple, a une limite de 65 535 fichiers par dossier. Voir "Combien de fichiers dans un répertoire sont trop nombreux?" sur Stack Overflow. Notez que l'utilisation des dossiers, comme je le suggère ci-dessus, réduit le risque de dépasser les limites du répertoire.
Y a-t-il un moyen plus efficace de s'y prendre?
Vous n'avez pas du tout besoin de stocker des données d'image dans votre base de données si vous suivez une convention simple. Lorsqu'un utilisateur télécharge une image de profil, par exemple, vous pouvez la renommer en profile.jpg
, puis la stocker dans /uploads/users/username/
. Maintenant, vous avez seulement besoin du nom d'utilisateur de l'utilisateur pour récupérer son image de profil. Vous n'avez plus besoin de stocker une référence à l'image dans la base de données. (Ou vous pouvez simplement nommer l'image theirusername.jpg
et la stocker dans /uploads/users/
- choisissez la convention qui vous convient le mieux.)
De même, lorsque l'utilisateur télécharge des images pour une révision, vous pouvez les stocker dans un dossier nommé /uploads/reviews/13/
. Le numéro 13 à la fin serait l'ID de révision - l'ID unique de cette révision tel qu'il est stocké dans la table de base de données. Pour afficher ces images, il vous suffit d’obtenir l’ID de révision pour récupérer ces images. (Pour savoir quelles images se trouvent dans un dossier, vous pouvez scanner le répertoire. Avec PHP, vous utilisez scandir () , par exemple.)
Stockez les informations sur l'image dans la base de données (nom d'utilisateur, identifiant de l'image, nom de fichier) et saisissez-les avec un JOIN.
Ce fil sur Stack Overflow discute de la même idée, bien que je ne puisse pas trouver le fil exact que je voulais référencer, ce qui donne de meilleures explications. Michael Andrews explique dans son blog quelques-unes des pratiques actuelles sur la manière de mettre en œuvre un système comme celui-ci ...
L'idée de base est que vous stockez l'image en hachant son contenu et en utilisant ce hachage comme nom de fichier.
Si plusieurs personnes téléchargent la même image, celle-ci ne sera stockée qu'une seule fois sur le serveur. Chaque fois que votre base de données ne contient plus de références à ce nom de fichier, vous êtes libre de le supprimer.