49 votes

Stockage d'un grand nombre d'images

J'envisage de développer ma propre galerie en PHP pour stocker de nombreuses photos, peut-être des dizaines de milliers.

Dans la base de données, je pointerai vers l'url de l'image, mais voici le problème : je sais qu'il n'est pas pratique de les avoir toutes dans le même répertoire sur le serveur, car cela ralentirait l'accès, alors comment les stocker ? Une sorte d'arbre basé sur le nom du jpeg/png ?

Quelles règles de partitionnement des images me conseillez-vous ?

(Il sera axé sur l'utilisation de cheapo dot coms, donc aucune manipulation avec le serveur n'est possible).

47voto

Toon Krijthe Points 36327

Nous avons eu un problème similaire dans le passé. Et nous avons trouvé une bonne solution :

  • Donnez à chaque image un guide unique.
  • Créez un enregistrement de base de données pour chaque image contenant le nom, l'emplacement, le guide et l'emplacement éventuel des sous-images (vignettes, taille réduite, etc.).
  • Utilisez les premiers (un ou deux) caractères du guide pour déterminer le dossier de premier niveau.
  • Si les dossiers contiennent trop de fichiers, divisez-les à nouveau. Mettez à jour les références et vous êtes prêt à partir.
  • Si le nombre de fichiers et les accès sont trop élevés, vous pouvez répartir les dossiers sur différents serveurs de fichiers.

Nous avons constaté qu'en utilisant les guides, vous obtenez une division plus ou moins uniforme. Et ça a marché comme sur des roulettes.

Liens qui pourraient aider à générer un identifiant unique :

11voto

Clayton Points 841

J'ai travaillé sur un système de gestion électronique des documents il y a quelques années, et nous avons fait à peu près ce que Gamecat et wic ont suggéré.

C'est-à-dire, attribuer à chaque image un ID unique, et l'utiliser pour dériver un chemin relatif vers le fichier image. Nous avons utilisé un MOD similaire à celui suggéré par wic, mais nous avons autorisé 1024 dossiers/fichiers à chaque niveau, avec 3 niveaux, afin de pouvoir supporter des fichiers de 1G.

Nous avons cependant supprimé l'extension des fichiers. Les enregistrements de la base de données contenaient le type MIME, l'extension n'était donc pas nécessaire.

Je ne recommande pas de stocker l'URL complète dans l'enregistrement de la base de données, mais seulement l'ID de l'image. Si vous stockez l'URL, vous ne pouvez pas déplacer ou restructurer votre stockage sans convertir votre BD. Une URL relative serait acceptable puisque de cette façon vous pouvez au moins déplacer le dépôt d'images, mais vous aurez plus de flexibilité si vous stockez juste l'ID et dérivez l'URL.

De même, je ne recommande pas d'autoriser les références directes à vos fichiers d'images à partir du Web. Fournissez plutôt une URL vers un programme côté serveur (par exemple, Java Servlet), l'ID de l'image étant fourni dans la requête URL ( http://url.com/GetImage?imageID=1234 ).

La servlet peut utiliser cet ID pour consulter l'enregistrement de la base de données, déterminer le type MIME, dériver l'emplacement réel, vérifier les restrictions de sécurité, la journalisation, etc.

8voto

Martin Wickman Points 9628

En général, j'utilise simplement l'identifiant numérique de la base de données (auto-incrément), puis j'utilise l'opérateur modulo (%) pour déterminer où placer le fichier. C'est simple et évolutif. Par exemple, le chemin vers l'image avec l'id 12345 pourrait être créé comme ceci :

12345 % 100 = 45
12345 % 1000 = 345

Finit dans :

/home/joe/images/345/45/12345.png

Ou quelque chose comme ça.

Si vous utilisez Linux et le système de fichiers ext3, vous devez savoir qu'il existe des limites au nombre de répertoires et de fichiers que vous pouvez avoir dans un répertoire. La limite est de 32000 pour les répertoires, vous devez donc toujours vous efforcer de garder un nombre de répertoires faible.

7voto

Adrian Smith Points 6087

Je sais que ce n'est pas pratique de les avoir tous dans le même répertoire sur le serveur car cela ralentirait l'accès.

Il s'agit d'une hypothèse.

J'ai conçu des systèmes où des millions de fichiers étaient stockés à plat dans un seul répertoire, et cela fonctionnait parfaitement. C'est aussi le système le plus facile à programmer. La plupart des systèmes de fichiers des serveurs le supportent sans problème (mais il faut vérifier lequel vous utilisez).

http://www.databasesandlife.com/flat-directories/

5voto

Isaac Points 352

Lors de l'enregistrement des fichiers associés à un identifiant à incrémentation automatique, j'utilise quelque chose comme ce qui suit, qui crée trois niveaux de répertoire, chacun composé de 1000 répertoires, et 100 fichiers dans chaque répertoire de troisième niveau. Cela supporte ~ 100 milliards de fichiers.

si $id = 99532455444 alors le résultat suivant est /995/324/554/44

function getFileDirectory($id) {
    $level1 = ($id / 100000000) % 100000000;
    $level2 = (($id - $level1 * 100000000) / 100000) % 100000;
    $level3 = (($id - ($level1 * 100000000) - ($level2 * 100000)) / 100) % 1000;
    $file   = $id - (($level1 * 100000000) + ($level2 * 100000) + ($level3 * 100));

    return '/' . sprintf("%03d", $level1)
         . '/' . sprintf("%03d", $level2)
         . '/' . sprintf("%03d", $level3)
         . '/' . $file;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X