Mise à jour en 2012, lorsque nous constatons que les tailles d'image et le nombre d'images augmentent et augmentent, dans toutes les applications ...
Nous avons besoin d'une certaine distinction entre «image originale» et «image traitée», comme la vignette.
Comme le dit la réponse de Jcoby, il y a deux options, alors je recommande:
utilisez blob (Binary Large OBject): pour le magasin d'images d'origine, à votre table. Voir la réponse d'Ivan (pas de problème avec la sauvegarde des blobs!), Les modules supplémentaires fournis par PostgreSQL , les procédures, etc.
utiliser une base de données séparée avec DBlink : pour le magasin d'images d'origine, dans une autre base de données (unifiée / spécialisée). Dans ce cas, je préfère bytea , mais blob est presque le même. La séparation de la base de données est le meilleur moyen pour un "service Web d'image unifiée".
use bytea (BYTE Array): pour la mise en cache des images miniatures. Mettez en cache les petites images pour les envoyer rapidement au navigateur Web (pour éviter les problèmes de rendu) et 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 de la base de données est le moyen le plus simple, mais vérifiez vos besoins et les configurations de serveur (ex. Modules Apache): stocker les vignettes dans le système de fichiers peut être mieux, comparer les performances. N'oubliez pas qu'il s'agit d'un service Web (unifié), puis qu'il peut être stocké dans une base de données distincte (sans sauvegarde), desservant de nombreuses tables. Voir aussi le manuel des types de données binaires PostgreSQL , les tests avec la colonne bytea , etc.
NOTE1: aujourd'hui l'utilisation de «solutions doubles» (base de données + système de fichiers) est obsolète (!). Il y a de nombreux avantages à utiliser "uniquement la base de données" au lieu du double. PostgreSQL a des performances comparables et de bons outils pour l'exportation / importation / entrée / sortie.
NOTE2: rappelez-vous que PostgreSQL n'a que bytea , pas de BLOB d'Oracle par défaut : "Le standard 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 changé 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 changements (voir "Mode Wiki", vous pouvez éditer!), Pour relecture et pour les mises à jour .
La question est stable (réponse de @ Ivans '08 avec 19 votes), aidez-nous à améliorer ce texte.
Re réponse de jcoby:
bytea étant une colonne "normale" signifie également que la valeur est lue complètement en mémoire lorsque vous la récupérez. Blobs, en revanche, vous pouvez diffuser dans stdout. Cela aide à réduire l'empreinte mémoire du serveur. Surtout lorsque vous stockez 4 à 6 images MPix.
Aucun problème avec la sauvegarde des blobs. pg_dump fournit l'option "-b" pour inclure les gros objets dans la sauvegarde.
Donc, je préfère utiliser pg_lo_ *, vous pouvez le deviner.
Re 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 vous devez absolument le faire. 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 base de données). BTW, PostgreSQL est excellent pour préserver la cohérence.
Cependant, il est vrai que la réalité est souvent trop exigeante en termes de performances ;-), et elle vous pousse à servir les fichiers binaires 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 l'optimisation des performances.
la source
BYTEA
être une colonne «normale». Postgres prend en charge le streaming depuis / vers lesBYTEA
colonnes depuis de nombreuses années, ce qui signifie que vous n'avez pas à stocker le contenu en mémoire avant de le stocker dans la base de données.Dans la base de données, il existe deux options:
J'ai utilisé des colonnes bytea avec beaucoup de succès dans le passé, stockant plus de 10 Go d'images avec des milliers de lignes. La fonctionnalité TOAST de PG annule à peu près tout avantage des blobs. Vous devrez inclure des colonnes de métadonnées dans les deux cas pour le nom de fichier, le type de contenu, les dimensions, etc.
la source
Mise à jour rapide à la mi-2015:
Vous pouvez utiliser l' interface Postgres Foreign Data , pour stocker les fichiers dans une base de données plus appropriée. Par exemple, placez les fichiers dans un GridFS qui fait partie de MongoDB. Ensuite, utilisez https://github.com/EnterpriseDB/mongo_fdw pour y accéder dans Postgres.
Cela présente les avantages que vous pouvez y accéder / lire / écrire / sauvegarder dans Postrgres et MongoDB, en fonction de ce qui vous donne plus de flexibilité.
Il existe également des wrappers de données étrangers pour les systèmes de fichiers: https://wiki.postgresql.org/wiki/Foreign_data_wrappers#File_Wrappers
À titre d'exemple, vous pouvez utiliser celui-ci: https://multicorn.readthedocs.org/en/latest/foreign-data-wrappers/fsfdw.html (voir ici pour un bref exemple d'utilisation)
Cela vous donne l'avantage de la cohérence (tous les fichiers liés sont définitivement là) et de tous les autres ACID, alors qu'il y en a encore sur le système de fichiers réel, ce qui signifie que vous pouvez utiliser n'importe quel système de fichiers que vous voulez et que le serveur Web peut les servir directement ( La mise en cache du système d'exploitation s'applique également).
la source
Mise à jour à partir de 10 ans plus tard En 2008, les disques durs sur lesquels vous exécuteriez une base de données auraient des caractéristiques très différentes et un coût beaucoup plus élevé que les disques sur lesquels vous stockeriez des fichiers. De nos jours, il existe de bien meilleures solutions pour stocker des fichiers qui n'existaient pas il y a 10 ans et je révoquerais ce conseil et conseillerais aux lecteurs de regarder certaines des autres réponses de ce fil.
Original
Ne stockez pas d'images dans la base de données sauf si vous y êtes obligé. Je comprends qu'il ne s'agit pas d'une application Web, mais s'il n'y a pas d'emplacement de fichier partagé que vous pouvez pointer pour enregistrer l'emplacement du fichier dans la base de données.
alors peut-être que vous pouvez rapidement configurer un serveur Web et stocker les URL 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 mégapixels, en supposant une image de 500 Ko) 1,5 Go n'est pas beaucoup d'espace, les systèmes de fichiers sont bien mieux conçus pour stocker des fichiers volumineux qu'une base de données.
la source
Essayez ceci . J'ai utilisé le format LOB (Large Object Binary) pour stocker des documents PDF générés, dont certains avaient une taille de 10+ Mo, dans une base de données et cela a fonctionné à merveille.
la source
Si vos images sont petites, pensez à les stocker en base64 dans un champ de texte brut.
La raison en est que si base64 a une surcharge de 33%, avec une compression qui disparaît la plupart du temps. (Voir Quelle est la surcharge d'espace du codage Base64? ) Votre base de données sera plus grande, mais les paquets que votre serveur Web envoie au client ne le seront pas. En html, vous pouvez insérer base64 dans une balise <img src = "">, ce qui peut éventuellement simplifier votre application car vous n'aurez pas à servir les images sous forme de fichier binaire dans un navigateur séparé. La gestion des images sous forme de texte simplifie également les choses lorsque vous devez envoyer / recevoir du json, ce qui ne gère pas très bien le binaire.
Oui, je comprends que vous pouvez stocker le binaire dans la base de données et le convertir en / à partir de texte en entrant et en sortant de la base de données, mais parfois les ORM en font un problème. Il peut être plus simple de le traiter comme du texte simple, comme tous vos autres champs.
C'est certainement la bonne façon de gérer les vignettes.
(Les images d'OP ne sont pas petites, ce n'est donc pas vraiment une réponse à sa question.)
la source