120 votes

Stockage des images dans PostgreSQL

Bon, je travaille sur une application qui utilisera un back-end Linux exécutant PostgreSQL pour servir des images à une boîte Windows avec le front-end écrit en C#.NET, bien que le front-end ne devrait pas avoir d'importance. Ma question est la suivante :

  • Quelle est la meilleure façon de gérer le stockage des images dans Postgres ?

Les images font environ 4 à 6 mégapixels chacune, et nous en stockons plus de 3000. Il est également bon de noter que ce n'est pas une application web, il y aura tout au plus deux front-ends accédant à la base de données en même temps.

71voto

Peter Krauss Points 1888

En 2012, nous constatons que la taille des images et leur nombre ne cessent d'augmenter dans toutes les applications...

Nous avons besoin d'une distinction entre "image originale" et "image traitée", comme une vignette.

Comme le dit la réponse de Jcoby, il y a deux options, alors, je recommande :

  • utiliser blob (Binary Large OBject) : pour le stockage de l'image originale, à votre table. Voir la réponse d'Ivan (pas de problème pour sauvegarder les blobs !), Modules supplémentaires fournis par PostgreSQL , Mode d'emploi etc.

  • utiliser une base de données séparée avec DBlink pour le stockage de l'image originale, dans une autre base de données (unifiée/spécialisée). Dans ce cas, je préfère octeta mais blob est presque la même. La séparation des bases de données est la meilleure façon de créer un "service web d'images unifiées".

  • utiliser octeta (BYTE Array) : pour la mise en cache des images miniatures. La mise en cache des petites images permet de les envoyer rapidement au navigateur web (pour éviter les problèmes de rendu) et de réduire le traitement du serveur. Mettez également en cache les métadonnées essentielles, comme la largeur et la hauteur. La mise en cache par base de données est la méthode la plus simple, mais vérifiez vos besoins et la configuration de votre serveur (ex. modules Apache) : stocker les vignettes dans le système de fichiers peut être meilleur, comparez les performances. Rappelez-vous qu'il s'agit d'un service web (unifié), puis qu'il peut être stocké dans une base de données séparée (sans sauvegardes), servant de nombreuses tables. Voir aussi Manuel des types de données binaires PostgreSQL , tests avec la colonne bytea etc.

NOTE1 : aujourd'hui, l'utilisation de "double solution" (base de données+système de fichiers) est déprécié ( !). Il y a de nombreux avantages à utiliser "seulement la base de données" au lieu de dual. PostgreSQL a des performances comparables et de bons outils pour l'exportation/importation/entrée/sortie.

NOTE2 : n'oubliez pas que PostgreSQL ne dispose que de octeta , n'ont pas d'Oracle par défaut BLOB : "La norme SQL définit (...) BLOB. Le format d'entrée est différent de bytea, mais les fonctions et opérateurs fournis sont pour la plupart les mêmes", Manuel .


EDIT 2014 : Je n'ai pas modifié le texte original ci-dessus aujourd'hui (ma réponse était le 22 avril '12, maintenant avec 14 votes), J'ouvre la réponse pour vos modifications (voir "mode Wiki", vous pouvez modifier !), pour correction d'épreuves et pour les mises à jour .
La question est stable (réponse de @Ivans '08 avec 19 votes), s'il vous plaît, aidez à améliorer ce texte.

2 votes

Quelle est la référence pour "...l'utilisation de "solutions doubles" (base de données+système de fichiers) est dépréciée..." ?

0 votes

Quelques nouvelles de 2019 ! Depuis 2018 PostgREST supporte la sortie directe de octeta sur le web. Voir ce Configuration simple de NGINX pour l'utiliser. Voir Guide PostgREST sur la sortie binaire

52voto

Ivan Krechetov Points 6465

Re la réponse de jcoby :

Le fait que bytea soit une colonne "normale" signifie également que la valeur est entièrement lue en mémoire lorsque vous la récupérez. Les blobs, en revanche, peuvent être diffusés dans le stdout. Cela permet de réduire l'empreinte mémoire du serveur. En particulier, lorsque vous stockez des images de 4-6 MPix.

Pas de problème avec la sauvegarde des blobs. pg_dump fournit l'option "-b" pour inclure les gros objets dans la sauvegarde.

Je préfère donc utiliser pg_lo_*, vous l'aurez deviné.

Re la réponse de Kris Erickson :

Je dirais le contraire :). Lorsque les images ne sont pas les seules données que vous stockez, ne les stockez pas sur le système de fichiers, sauf si c'est absolument nécessaire. C'est un tel avantage d'être toujours sûr de la cohérence de vos données, et d'avoir les données "en un seul morceau" (la BD). BTW, PostgreSQL est excellent pour préserver la cohérence.

Cependant, la réalité est souvent trop exigeante en termes de performances ;-), et elle vous pousse à servir les fichiers binaires à partir du système de fichiers. Mais même dans ce cas, j'ai tendance à utiliser la base de données comme stockage "maître" pour les binaires, avec toutes les autres relations liées de manière cohérente, tout en fournissant un mécanisme de mise en cache basé sur le système de fichiers pour optimiser les performances.

15 votes

Après 10 ans, pensez-vous que vos arguments sont toujours valables ? Des mises à jour depuis lors ?

3 votes

@leventunver Non, les points à ne tiennent pas. Par exemple, le premier point concernant BYTEA étant une colonne "normale". Postgres a supporté streaming vers/depuis BYTEA pour de nombreuses années, ce qui signifie que vous n'avez pas besoin de stocker le contenu en mémoire avant de l'enregistrer dans la base de données.

29voto

jcoby Points 2389

Dans la base de données, il y a deux options :

  • bytea. Stocke les données dans une colonne, exportée dans le cadre d'une sauvegarde. Utilise les fonctions standard des bases de données pour sauvegarder et récupérer. Recommandé pour vos besoins.
  • blobs. Stocke les données en externe, et n'est normalement pas exporté dans le cadre d'une sauvegarde. Nécessite des fonctions de base de données spéciales pour la sauvegarde et la récupération.

J'ai utilisé les colonnes bytea avec beaucoup de succès dans le passé en stockant 10+gb d'images avec des milliers de lignes. La fonctionnalité TOAST de PG annule pratiquement tout avantage des blobs. Dans les deux cas, vous devrez inclure des colonnes de métadonnées pour le nom de fichier, le type de contenu, les dimensions, etc.

1 votes

10 Go, c'est peu :-( Je cherche une solution en TBs.

2 votes

@ValentinHeinitz Pour les TB, la version classique de Postgres a du mal, même avec des colonnes de texte plus petites.

20voto

Kris Erickson Points 16204

Mise à jour 10 ans plus tard En 2008, les disques durs sur lesquels vous feriez tourner une base de données auraient des caractéristiques bien différentes et un coût bien plus élevé que les disques sur lesquels vous stockeriez des fichiers. Il existe aujourd'hui de bien meilleures solutions pour le stockage des fichiers, qui n'existaient pas il y a dix ans. Je révoquerais ce conseil et conseillerais aux lecteurs de consulter d'autres réponses dans ce fil.

Original

Ne stockez pas d'images dans la base de données, sauf si vous devez absolument le faire. Je comprends qu'il ne s'agit pas d'une application Web, mais s'il n'existe pas d'emplacement de fichier partagé vers lequel vous pouvez pointer, enregistrez l'emplacement du fichier dans la base de données.

//linuxserver/images/imagexxx.jpg

alors vous pouvez peut-être configurer rapidement un serveur web et stocker les urls web dans la base de données (ainsi que le chemin local). Alors que les bases de données peuvent gérer des LOB et 3000 images (4-6 Megapixels, en supposant 500K par image), 1.5 Gigs n'est pas beaucoup d'espace, les systèmes de fichiers sont bien mieux conçus pour stocker de gros fichiers que ne l'est une base de données.

15 votes

Mais vous devez trouver un moyen de répartir les fichiers sur plusieurs répertoires. Les systèmes de fichiers ne sont pas très performants pour stocker des millions de fichiers dans un seul répertoire. simple répertoire (en fait, dix mille est déjà un problème)

1 votes

Ça ne répond pas à la question originale. Personnellement, je cherche à stocker des images dans Postgres simplement parce que je veux SQL comme couche d'abstraction et que je ne veux pas non plus gérer les fichiers dans mon système de fichiers ext4.

0 votes

Je suis partagé, cela ne répond pas à la question, mais j'ai voté pour, parce que c'est une meilleure réponse qu'une réponse à la question.

6voto

Mike Reedell Points 1149

Essayez ce . J'ai utilisé le format Large Object Binary (LOB) pour stocker des documents PDF générés, dont certains faisaient plus de 10 Mo, dans une base de données et cela a fonctionné à merveille.

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