web-dev-qa-db-fra.com

Existe-t-il des problèmes de performances lors du stockage de fichiers dans PostgreSQL?

Est-ce que le stockage de fichiers comme des pages HTML, des images, des fichiers PDF, etc. est correct dans une table dans PostgreSQL ou est-ce lent? J'ai lu quelques articles disant que ce n'est pas recommandé, mais je ne sais pas si c'est vrai.

Les types de colonnes que j'ai en tête sont BLOB (pour autant que je sache qu'ils stockent dans un fichier) ou bytea, mais d'autres sont également applicables.

41
Renato Dinhani

Vous avez essentiellement deux choix. Vous pouvez stocker les données directement dans la ligne ou utiliser la fonction de gros objet. Puisque PostgreSQL utilise désormais quelque chose appelé TOAST pour déplacer de grands champs hors de la table, il ne devrait pas y avoir de pénalité de performance associée au stockage direct de grandes données dans la ligne. Il reste une limite de 1 Go dans la taille d'un champ. Si cela est trop limité ou si vous voulez une API de streaming, vous pouvez utiliser la fonction de gros objet, qui vous donne quelque chose de plus comme des descripteurs de fichiers dans la base de données. Vous stockez l'ID LO dans votre colonne et pouvez lire et écrire à partir de cet ID.

Personnellement, je vous suggère d'éviter l'installation des gros objets, sauf si vous en avez absolument besoin. Avec TOAST, la plupart des cas d'utilisation sont couverts en utilisant simplement la base de données comme vous vous y attendez. Avec des objets volumineux, vous vous imposez une charge de maintenance supplémentaire, car vous devez garder une trace des identifiants LO que vous avez utilisés et assurez-vous de les dissocier lorsqu'ils ne sont plus utilisés (mais pas avant) ou qu'ils resteront dans votre répertoire de données prenant de la place pour toujours. Il y a aussi beaucoup d'installations qui ont un comportement exceptionnel autour d'elles, dont les détails m'échappent car je ne les utilise jamais.

Pour la plupart des gens, la grande pénalité de performance associée au stockage de données volumineuses dans la base de données est que votre logiciel ORM extraira les données volumineuses sur chaque requête, sauf si vous le lui demandez expressément de ne pas le faire. Vous devez prendre soin de dire à Hibernate ou à tout ce que vous utilisez de traiter ces colonnes comme grandes et de ne les récupérer que lorsqu'elles sont spécifiquement demandées.

59
Daniel Lyons

Le type BLOB (LO) stocke les données dans des blocs de 2 Ko dans des pages de tas PostgreSQL standard dont la taille par défaut est de 8 Ko. Ils ne sont pas stockés en tant que fichiers cohésifs indépendants dans le système de fichiers - par exemple, vous ne pourrez pas localiser le fichier, faire une comparaison octet par octet et vous attendre à ce qu'il soit le même que les données de fichier d'origine que vous chargé dans la base de données, car il existe également des en-têtes de page de tas Postgres et des structures qui délimitent les morceaux.

Vous devez éviter d'utiliser l'interface Large Object (LO) si votre application doit fréquemment mettre à jour les données binaires, et en particulier si cela implique beaucoup de petites écritures à accès aléatoire, qui, en raison de la façon dont PostgreSQL implémente le contrôle de concurrence (MVCC) peut conduire à une explosion de la quantité d'espace disque utilisé jusqu'à ce que vous VIDEZ la base de données. Le même résultat est probablement également applicable aux données stockées en ligne dans une colonne de type bytea ou même TOAST'd.

Cependant, si vos données suivent un modèle d'écriture unique (par exemple, téléchargez une image PNG et ne la modifiez jamais après), cela devrait être correct du point de vue de l'utilisation du disque.

Voir ce fil de liste de diffusion pgsql-general pour une discussion plus approfondie.

14
singularsyntax