Quel est le meilleur endroit pour stocker les images téléchargées, la base de données SQL ou le système de fichiers sur disque?


147

J'écris une application qui permet aux utilisateurs de télécharger des images sur le serveur. J'attends environ 20 images par jour toutes jpeg et probablement pas éditées / redimensionnées. (Ceci est une autre question, comment redimensionner les images côté serveur avant de les stocker. Peut-être que quelqu'un peut s'il vous plaît déposer une ressource .NET pour cela dans le commentaire ou plus). Je me demande maintenant quel est le meilleur endroit pour stocker les images téléchargées.

  • Stockez les images sous forme de fichier dans le système de fichiers et créez un enregistrement dans une table avec le chemin exact de cette image.

  • Ou, stockez l'image elle-même dans une table en utilisant un type de données "image" ou "données binaires" du serveur de base de données.

Je vois des avantages et des inconvénients dans les deux. J'aime a) parce que je peux facilement déplacer les fichiers et avoir juste à changer l'entrée de la table. D'un autre côté, je n'aime pas stocker des données commerciales sur le serveur Web et je ne veux pas vraiment connecter le serveur Web à une autre source de données contenant des données commerciales (pour des raisons de sécurité) J'aime b) parce que toutes les informations sont en un seul endroit et facilement accessible par une requête. D'un autre côté, la base de données deviendra très volumineuse très bientôt. L'externalisation de ces données pourrait être plus difficile.


2
Je ne l'ai pas trouvé, où?
Tobias


Réponses:


95

Je stocke généralement des fichiers sur le système de fichiers, car c'est pour cela qu'il est là, bien qu'il y ait des exceptions. Pour les fichiers, le système de fichiers est la solution la plus flexible et la plus performante (généralement).

Il y a quelques problèmes avec le stockage des fichiers sur une base de données - les fichiers sont généralement beaucoup plus volumineux que votre ligne moyenne - les ensembles de résultats contenant de nombreux fichiers volumineux consommeront beaucoup de mémoire. De plus, si vous utilisez un moteur de stockage qui utilise des verrous de table pour les écritures (ISAM par exemple), votre table de fichiers peut être souvent verrouillée en fonction de la taille / du taux de fichiers que vous y stockez.

En ce qui concerne la sécurité - je stocke généralement les fichiers dans un répertoire qui est en dehors de la racine du document (non accessible via une requête http) et je les sers via un script qui vérifie d'abord l'autorisation appropriée.


7
Pourriez-vous s'il vous plaît m'expliquer le dernier paragraphe (concernant la sécurité) en termes de détails techniques ou tout pointeur serait très utile. Je vous remercie.
VishwaKumar

39
(Pour tous les googleurs) Si la racine de votre site est configurée dans un dossier "public" (comme dans my_website / public / au lieu de simplement my_website /), vous pouvez stocker les images dans le dossier my_website / my_images avec le reste de votre appli. Ensuite, vos balises img feraient référence à "mon_site_web / image.php? Img_id = 55" au lieu de "mon_site_web / avatar.png", et votre script image.php, après vérification de vos informations d'identification et analyse de l'identifiant que vous lui avez donné, renvoie le véritable image. De cette façon, l'image n'est visible que par l'utilisateur correctement connecté.
Captain Hypertext

8
hé capitaine, vous devriez transformer cela en une réponse réelle afin que vous puissiez obtenir des points $$$
Andrew

4
s'il vous plaît ajouter quelques notes supplémentaires sur la sécurité / empêcher les fichiers de détruire votre site Web
Andrew

1
Cela ne serait pas mis à l'échelle, il y a une limite sur le nombre de fichiers dans le dossier et si vous prévoyez de diviser vos fichiers en plusieurs dossiers, cela ajouterait des complexités d'indexation des fichiers (pour identifier où le fichier est réellement stocké). De plus, la recherche sera très lente.
Hardik

43

Le seul avantage de l'option B est d'avoir toutes les données dans un seul système, mais c'est un faux avantage! Vous pouvez affirmer que votre code est également une forme de données et peut donc également être stocké dans une base de données - comment l'aimeriez-vous?

Sauf si vous avez un cas unique:

  • La logique métier appartient au code.
  • Les données structurées appartiennent à la base de données (relationnelle ou non relationnelle).
  • Les données en masse appartiennent au stockage (système de fichiers ou autre).

Fichiers, code, données

Il n'est pas nécessaire d'utiliser le système de fichiers pour conserver les fichiers. Au lieu de cela, vous pouvez utiliser le stockage dans le cloud (tel qu'Amazon S3 ) ou l'infrastructure en tant que service (tel que Uploadcare ):

https://uploadcare.com/upload-api-cloud-storage-and-cdn/

Mais stocker des fichiers dans la base de données est une mauvaise idée.



14

Je sais que c'est un ancien message. Mais de nombreux visiteurs de cette page n'obtiennent rien en rapport avec la question. Surtout pour un débutant.

Comment télécharger et stocker des images ou des fichiers sur notre site Web:

Pour un site Web statique, il n'y a peut-être pas de problème car le stockage de fichiers pour certains hébergements partagés reste suffisant. Le problème vient d'un site Web dynamique lorsqu'il s'agrandit. Une plus grande taille dans la base de données peut être gérée, mais une taille plus importante dans des fichiers tels que des images devient un problème. Il existe deux types d'images dans un site Web:

  1. Les images proviennent de l'administrateur du blog dynamique. Habituellement, ces images ont été optimisées avant le téléchargement.

  2. Images des utilisateurs dans le cas où les utilisateurs sont autorisés à télécharger des images telles qu'un avatar. Ou les utilisateurs peuvent créer du contenu de blog et mettre des images à partir de l'éditeur de texte. Ce genre d'images est difficile à prédire la taille. Les utilisateurs peuvent télécharger de grandes images uniquement pour le petit contenu en redimensionnant la taille de la vue mais pas en redimensionnant la taille de l'image.

En ignorant l'article no. 1 ci-dessus, solution rapide pour l'article no. 2 peut être temporairement résolu par les conseils suivants si nous n'avons pas de fonctionnalité d'optimisation d'image sur notre site Web:

  1. N'autorisez pas les utilisateurs à télécharger directement depuis l'éditeur de texte en les redirigeant vers la galerie d'images. Sur cette page, les utilisateurs doivent télécharger le fichier à l'avance avant de pouvoir l'intégrer dans le contenu. Cette méthode est appelée en tant que gestionnaire de fichiers.

  2. Utilisez une fonction de recadrage d'image pour que les utilisateurs téléchargent des images. Cela limitera la taille de l'image même les utilisateurs téléchargent de très gros fichiers. L'image finale est le résultat de l'image recadrée. Nous pouvons définir la taille côté serveur et n'accepter que par exemple 500Kb ou moins.

Maintenant, ce n'est que temporaire. Pour la solution finale, la question est répétée:

  • Comment gérer un grand stockage d'images?
  • Redimensionnez ou modifiez l'extension.
  • Comment un site Web ou un commerce électronique de grande ou moyenne taille gère-t-il le stockage des fichiers de leurs images?

Ce que nous pouvons faire alors:

  1. Migrez depuis l'hébergement de partage VPS. Pas assez? Puis plus haut en passant à Dedicated.

  2. Créez votre propre serveur pour le stockage de fichiers. Googler pour le faire. Ce n'est pas aussi difficile que vous le pensez. Certaines personnes le font pour leur site Web.

  3. Le moyen le plus simple consiste à utiliser le service de stockage de fichiers CDN.

D'accord, 1 et 2 sont un peu chers. Mais non 3 je pense que c'est la meilleure solution.

Certains services CDN vous permettent de stocker autant de fichiers Web que vous le souhaitez.

Question, "comment télécharger un fichier sur CDN à partir de notre site Web?"

Ne vous inquiétez pas, une fois que vous vous inscrivez, généralement gratuitement, vous obtiendrez des conseils sur la façon de télécharger des fichiers et d'obtenir leur lien depuis / vers votre site Web. Vous obtiendrez une API en plus. C'est facile.

Certains fournisseurs nous offrent un service gratuit pendant 14 jours avec un stockage et une bande passante limités. Mais ce sera bien comme point de départ. Le seul problème est que «les gens n'essaient jamais».

J'espère que cela aidera pour les débutants.


13

Nous avons eu des clients insister sur l'option B (stockage de base de données) à plusieurs reprises sur quelques backends différents, et nous avons toujours fini par revenir à l'option A (stockage du système de fichiers).

Les grands BLOB comme celui-ci n'ont tout simplement pas été suffisamment bien gérés, même par SQL Server 2005, qui est le dernier sur lequel nous l'avons essayé.

Plus précisément, nous avons vu de graves ballonnements et je pense peut-être des problèmes de verrouillage.

Une autre remarque: si vous utilisez un stockage basé sur NTFS (serveur Windows, etc.), vous pouvez envisager de trouver un moyen de mettre des milliers et des milliers de fichiers dans un répertoire. Je ne sais pas pourquoi, mais parfois le système de fichiers ne fait pas bien face à cette situation. Si quelqu'un en sait plus à ce sujet, j'aimerais l'entendre.

Mais j'essaie toujours d'utiliser des sous-répertoires pour casser un peu les choses. La date de création fonctionne souvent bien pour cela:

Images / 2008/12/17 / .jpg

... Cela fournit un niveau de séparation décent et aide également un peu lors du débogage. Les clients Explorer et FTP peuvent s'étouffer un peu lorsqu'il y a des répertoires vraiment énormes.

EDIT: Juste une note rapide pour 2017, dans les versions plus récentes de SQL Server, il existe de nouvelles options pour gérer de nombreux BLOB qui sont censées éviter les inconvénients dont j'ai parlé.

EDIT: Note rapide pour 2020, le stockage Blob dans AWS / Azure / etc est également une option depuis des années maintenant. Cela convient parfaitement à de nombreux projets Web, car il est bon marché et peut souvent simplifier certains problèmes liés au déploiement, à la mise à l'échelle sur plusieurs serveurs, au débogage d'autres environnements si nécessaire, etc.


4
Bon avertissement sur le nombre de fichiers sur le même répertoire. Cela peut donner des erreurs trop difficiles à trouver dans un environnement de production.
digao_mb

1
J'avais déjà rencontré ce problème. NTFS s'est comporté de manière imprévisible avec quelque 10 000 fichiers dans un dossier.
Faiz

1
Pas seulement NTFS mais aussi BTRFS, qui a également un problème avec d'énormes quantités d'images dans un dossier. À savoir si vous essayiez, lscela prendrait une éternité (se bloque). Ou supprimez.
sunapi386

11

J'ai récemment créé une application PHP / MySQL qui stocke les fichiers PDF / Word dans une table MySQL (jusqu'à 40 Mo par fichier jusqu'à présent).

Avantages:

  • Les fichiers téléchargés sont répliqués sur le serveur de sauvegarde avec tout le reste, aucune stratégie de sauvegarde distincte n'est nécessaire (tranquillité d'esprit).
  • La configuration du serveur Web est légèrement plus simple car je n'ai pas besoin d'avoir un dossier / upload et de dire à toutes mes applications où il se trouve.
  • J'utilise des transactions pour des modifications afin d'améliorer l'intégrité des données - je n'ai pas à m'inquiéter des fichiers orphelins et manquants

Les inconvénients:

  • mysqldump prend maintenant beaucoup de temps car il y a 500 Mo de données de fichier dans l'une des tables.
  • Globalement pas très efficace en mémoire / processeur par rapport au système de fichiers

J'appellerais ma mise en œuvre un succès, elle prend en charge les exigences de sauvegarde et simplifie la mise en page du projet. La performance est bonne pour les 20 à 30 personnes qui utilisent l'application.


6

J'utilise des images téléchargées sur mon site Web et je dirais certainement l'option a).

Une autre chose que je recommande vivement est de changer immédiatement le nom du fichier de ce que l'utilisateur a nommé la photo, en quelque chose de plus gérable. Par exemple, quelque chose avec la date et l'heure pour identifier de manière unique chaque image.

Cela permet également de dépouiller le nom de fichier de l'utilisateur de tout caractère étrange pour éviter de futures complications.


6

Redimensionnez définitivement l'image et vérifiez son format si vous le pouvez. Il y a eu des cas de fichiers malveillants téléchargés et servis par des hôtes involontaires - par exemple, le GIFAR vulnérabilité vous permettait de cacher une applet Java malveillante dans un fichier GIF, qui serait alors capable de lire les cookies dans le contexte actuel et de les envoyer à un autre site pour une attaque de script intersite. Le redimensionnement des images empêche généralement cela, car il détruit le code intégré. Bien que cette attaque ait été corrigée par des correctifs JVM, servir naïvement des fichiers binaires sans les nettoyer vous ouvre à toute une gamme de vulnérabilités.

N'oubliez pas que la plupart des antivirus ne peuvent s'exécuter que sur le système de fichiers - si vous stockez vos binaires dans la base de données, vous ne pourrez pas exécuter un scanner contre eux très facilement.


4

Il existe une sorte d'approche hybride dans SQL Server 2008 appelée le type de données filestream dont on a parlé sur RunAs Radio # 74 , qui est en quelque sorte le meilleur des deux mondes. La plupart des gens n'ont pas l'otion 2008, mais si vous le faites, cette option a l'air plutôt cool


4

C'est essentiellement ce que je fais.

  1. Stockez une image téléchargée dans un répertoire ou une mémoire temporaire.
  2. Traitez cette image avant de la stocker définitivement. 2.1. Corrections de couleur 2.2. Compresser 2.3. Créer plusieurs copies en fonction des dimensions de l'image 2.4. Renommer avec les suffixes .xl, .lg, .md, .sm etc.
  3. Emballez tous les fichiers image traités (à partir d'un seul fichier) dans un dossier avec le nom de dossier idqui sera stocké dans la base de données pour n'importe quelle ligne / document avec image file name(ou peut être un nom aléatoire comme nom d'image).
  4. Créez un dossier aaaa / mm / j path s'il n'existe pas. Par exemple, le 21/08/2016. Souvenez-vous de ce chemin et stockez-le dans la base de données pour le même document et la même ligne.
  5. Déplacez le iddossier d' image vers le pathdossier. (Le dossier Path peut se trouver dans le dossier / var / web-content.)
  6. Videz la mémoire tampon ou supprimez le fichier temporaire.

Lorsque vous devez accéder à une image mentionnée dans un document, vous disposez du chemin et de l'ID du dossier contenant les images. Par exemple/var/web-content/{{path}}/{{id}}/image-file-name.sm.jpg

De cette façon, si vous devez supprimer tous les fichiers image traités, supprimez simplement le dossier et son contenu de manière récursive.


3

La plupart des implémentations sont l'option A.

Avec l'option B, vous ouvrez une grande boîte de whoop4ss lorsque vous rassemblez ces bits de la base de données dans quelque chose qui peut être affiché sur un navigateur ... De plus, si la base de données est en panne, les images ne sont pas disponibles.

Je ne pense pas que l'espace soit trop un problème ... Les lecteurs de téraoctets coûtent maintenant quelques centaines de dollars.

Nous mettons en œuvre l'option A car nous n'avons ni le temps ni les ressources pour faire l'option B.


3

Pour le redimensionnement automatique, essayez imagemagick ... il est utilisé pour de nombreux systèmes de gestion de contenu / photo open source majeurs ... et je crois qu'il existe des extensions .net pour cela.


2

Nous utilisons A. Je le mettrais sur un lecteur partagé (sauf si vous ne prévoyez pas d'exécuter plus d'un serveur).

Si le moment vient où cela ne vous convient pas, vous pouvez étudier les mécanismes de mise en cache.


2

Absolument, positivement option A. D'autres ont mentionné que les bases de données ne traitent généralement pas bien les BLOB, qu'elles soient conçues pour le faire ou non. Les systèmes de fichiers, par contre, vivent pour ce genre de choses. Vous avez la possibilité d'utiliser la répartition RAID, de diffuser des images sur plusieurs disques, voire de les diffuser sur des serveurs géographiquement disparates.

Un autre avantage est que vos sauvegardes / réplication de base de données seraient monstrueuses.



2

Pour des raisons de sécurité, il est également recommandé d'éviter les problèmes causés par le reniflage de contenu d' IE, qui peut permettre aux attaquants de télécharger du JavaScript dans des fichiers image, qui pourraient être exécutés dans le contexte de votre site. Vous voudrez peut-être transformer les images (les recadrer / les redimensionner) avant de les stocker pour éviter ce type d'attaque. Cette réponse a d'autres idées.


2

Eh bien, j'ai un projet similaire où les utilisateurs téléchargent des fichiers sur le serveur. De mon point de vue, l'option a) est la meilleure solution car elle est plus flexible. Ce que vous devez faire est de stocker les images dans un dossier protégé classé par sous-répertoires. Le répertoire principal doit être mis en place par l'administrateur car le contenu ne doit pas exécuter de scripts (très important) et protégé (lecture, écriture) pour ne pas être accessible en requête http.

J'espère que ceci vous aide.


1

S'il s'agit de petits fichiers qui n'auront pas besoin d'être modifiés, l'option B n'est pas une mauvaise option. Je préfère cela à l'écriture de logique pour stocker des fichiers et traiter des problèmes de structure de répertoires fous. Avoir beaucoup de fichiers dans un répertoire est mauvais. emkay?

Si les fichiers sont volumineux ou nécessitent une édition constante, en particulier à partir de programmes comme Office, l'option A est votre meilleur choix.

Dans la plupart des cas, c'est une question de préférence, mais si vous choisissez l'option A, assurez-vous simplement que les répertoires ne contiennent pas trop de fichiers. Si vous choisissez l'option B, faites en sorte que la table contenant les données BLOB soit dans sa propre base de données et / ou groupe de fichiers. Cela facilitera la maintenance, en particulier les sauvegardes / restaurations. Vos données habituelles sont probablement assez petites, tandis que vos données d'image seront énormes au fil du temps.


1

Cela dépend de vos besoins, en particulier du volume, des utilisateurs et de la fréquence de recherche. Mais, pour les petits ou moyens bureaux, la meilleure option est d'utiliser une application comme Apple Photos ou Adobe Lighroom. Ils sont spécialisés pour stocker, cataloguer, indexer et organiser ce type de ressources. Mais, pour les grandes organisations, avec de fortes exigences de stockage et un nombre élevé d'utilisateurs, il est recommandé d'instancier une plateforme de gestion de contenu avec une gestion des actifs numériques, comme Nuxeo ou Alfresco; les deux offres de très bonnes ressources gèrent de très gros volumes de données avec des méthodes simplifiées pour les récupérer. Et, très important: il existe une option gratuite (open source) pour les deux plates-formes.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.