Je crée actuellement une application Web qui permet aux utilisateurs de stocker et de partager des fichiers, d'une taille allant de 1 à 10 Mo.
Il me semble que le stockage des fichiers dans une base de données ralentira considérablement l’accès à la base de données.
Est-ce une préoccupation valable? Est-il préférable de stocker les fichiers dans le système de fichiers et d'enregistrer le nom de fichier et le chemin d'accès dans la base de données? Existe-t-il des meilleures pratiques relatives au stockage de fichiers lorsque vous travaillez avec une base de données?
Je travaille en PHP et MySQL pour ce projet, mais le problème est le même pour la plupart des environnements ( Ruby on Rails , PHP , .NET ) et des bases de données (MySQL, PostgreSQL ).
10MB
aussi grand dans un système moderne.Réponses:
Raisons en faveur du stockage de fichiers dans la base de données:
Raison contre le stockage de fichiers dans la base de données:
FILESTREAM
objet SQL Server, et si vous devez migrer vers un autre système de base de données.OMI, considérer que le stockage des fichiers dans la base de données est ou non "mauvais" nécessite davantage d'informations sur les circonstances et les exigences. La taille et / ou le nombre de fichiers seront-ils toujours petits? Ne prévoyez-vous pas utiliser le stockage en nuage? Les fichiers seront-ils servis sur un site Web ou un exécutable binaire, comme une application Windows?
En général, mon expérience a montré que le stockage des chemins est moins coûteux pour l'entreprise, même en tenant compte du manque d'ACID et de la possibilité d'orphelins. Cependant, cela ne signifie pas qu'Internet ne soit pas légion et que le manque de contrôle ACID ne tourne pas rond avec le stockage de fichiers, mais cela signifie en général que cette solution est plus facile à créer, à comprendre et à maintenir.
la source
Dans de nombreux cas, c'est une mauvaise idée. Cela va gonfler les fichiers de la base de données et causer plusieurs problèmes de performances. Si vous collez les gouttes dans une table avec un grand nombre de colonnes, c'est encore pire.
Pourtant! Certaines bases de données, telles que SQL Server, ont un type de colonne FILESTREAM. Dans ce cas, vos données sont en réalité stockées dans un fichier séparé sur le serveur de base de données et seul un identifiant du fichier est enregistré dans la table. Dans ce cas, je ne vois pas beaucoup de raisons de ne pas conserver les données sur le serveur SQL. Les fichiers sont automatiquement inclus dans la sauvegarde du serveur, et la base de données et les fichiers ne sont jamais désynchronisés. Le problème avec la suggestion de Tony de stocker les noms de fichiers est que la base de données et le système de fichiers peuvent ne plus être synchronisés. La base de données affirmera qu'un fichier existe lorsqu'il a été supprimé sur le disque. Si un processus modifie la base de données puis se bloque, les fichiers et la base de données ne correspondront pas (c.-à-d. Aucun ACID avec des fichiers en dehors d'une base de données).
la source
Oui, c'est une mauvaise pratique.
Impact sur les performances de la base de données:
SELECT
colonne BLOB, vous aurez toujours un accès disque, tandis que sans BLOB, vous aurez une chance d'obtenir des données directement à partir de la RAM (la base de données à haut débit sera optimisée pour s'adapter aux tableaux dans la RAM);Avantage de vitesse - aucun ! Bien que certains systèmes de fichiers plus anciens ne gèrent pas correctement les répertoires contenant des millions de fichiers, la plupart des systèmes modernes ne rencontrent aucun problème et utilisent en fait le même type de structures de données que les BD (généralement les arbres B). Par exemple, ext4 (système de fichiers Linux par défaut) utilise Htree .
Conclusion: cela gênera les performances de votre base de données et n'améliorera pas les performances de récupération des fichiers.
, Puisque vous aussi parler de l' application Web - service de fichiers statiques directement à partir de système de fichiers en utilisant webserver moderne, qui peut faire
sendfile()
syscall est énorme amélioration de la performance. Ceci n'est bien sûr pas possible si vous récupérez des fichiers de la base de données. Considérons par exemple ce point de référence montrant que Ngnix fait 25 000 req / s avec 1 000 connexions simultanées sur un ordinateur portable bas de gamme. Ce type de charge ferait frire n'importe quel type de DB.la source
Je serais pragmatique à ce sujet et suivrais le principe "ne pas optimiser pour le moment". Définissez la solution qui a du sens pour le moment et que vous avez les ressources de développement à mettre en œuvre correctement. Il y a beaucoup de problèmes potentiels . Mais ceux-ci ne deviennent pas nécessairement de vrais problèmes. Par exemple, ce ne serait probablement pas un problème si vous avez 100 utilisateurs. Cela pourrait être un problème si vous avez 100 000 ou 10 000 000 utilisateurs. Mais dans ce dernier cas, il devrait y avoir une base pour plus de ressources de développement pour traiter toutes les questions.
Mais stocker les données dans la base de données vous évite de traiter d'autres problèmes, par exemple, où les fichiers doivent-ils être stockés, comment doivent-ils être sauvegardés, etc. Comme vous écrivez une application Web, ce serait une très bonne idée pour des raisons de sécurité. pour vous assurer que le processus hébergeant l'application n'a pas d'accès en écriture au système de fichiers, vous devez donc configurer le serveur de sorte que ce processus dispose d'un accès en lecture / écriture au dossier dans lequel les données sont stockées.
Personnellement, je choisirais de stocker les données dans la base de données, mais je m'assurerais que les BLOBS ne sont pas lus tant qu'ils ne sont pas nécessaires, c'est-à-dire qu'aucun "SELECT * FROM ..." n'est exécuté sur les tables contenant des blogs. Et je m'assurerais que la conception facilite le déplacement des données de la base de données vers le système de fichiers si vous rencontrez des problèmes de performances. Par exemple, stockez les informations sur le fichier dans une table de fichiers distincte , gardant ainsi les informations du fichier à l'écart des autres entités commerciales.
En supposant que vous ayez une classe File pour représenter un fichier lu dans la base de données, l'impact de son déplacement ultérieur sur le codage sera minime.
la source
Microsoft a publié un livre blanc à ce sujet il y a quelques années. Il se concentre sur SqlServer, mais vous pouvez y trouver des informations intéressantes:
Une version très concise de leur conclusion est la suivante:
Je vous recommanderais de rédiger de petits tests pour votre cas d'utilisation particulier. Gardez à l'esprit que vous devez vous méfier des effets de cache. (J'ai été stupéfait la première fois que j'ai obtenu des vitesses de sauvegarde sur disque qui semblaient avoir des débits plus élevés que physiquement possible!)
la source
La sagesse conventionnelle de stocker des fichiers en dehors de la base de données pourrait ne plus être valable. Par principe, je privilégierais l’intégrité au détriment de la vitesse, et avec un SGBD moderne, vous pouvez avoir les deux.
Tom Kyte semble être d' accord :
la source
Oui.
Si vous servez un fichier à partir de votre système de fichiers, votre serveur Web peut utiliser un code du noyau tel que sendfile () sous BSD ou Linux pour copier le fichier directement dans le socket. C'est très rapide et très efficace.
Servir des fichiers en dehors de la base de données signifie que vous devez copier les données du disque du serveur de base de données dans la mémoire du serveur de base de données, puis de la mémoire du serveur de base de données vers le port réseau du serveur de base de données, puis du processus réseau vers le processus de votre serveur Web, puis de nouveau vers le serveur. connexion réseau sortante.
Sauf si vous avez une très bonne raison de ne pas le faire, il est toujours préférable de servir des fichiers statiques à partir du système de fichiers.
la source
Le célèbre Tom Kyte a écrit qu’ils (Oracle) utilisaient la base de données Oracle comme serveur de fichiers et que cela fonctionnait parfaitement, même plus rapidement que le système de fichiers normal, avec une transaction complète, sans perte de performances et avec une sauvegarde unique.
Oui, mais attention, ils sont le producteur de la base de données Oracle. Pour tout autre utilisateur, il existe des problèmes de coûts. L'utilisation d'une base de données commerciale telle qu'Oracle pour le stockage de fichiers est tout simplement inefficace.
Cependant, avec PostgreSQL par exemple, vous pouvez simplement exécuter une autre instance de base de données uniquement pour le stockage d'objets blob. Vous avez alors un support transactionnel complet. Mais la transposition coûte de l’espace DB. Il est nécessaire que la base de données stocke plusieurs instances de blob pour plusieurs transactions simultanées. Sous PostgreSQL, c'est le plus pénible, car cette base de données stocke les doublons de blobs créés pour une transaction, même s'ils ne sont plus nécessaires, jusqu'à la fin du processus VACUUM.
Avec le stockage de système de fichiers, par contre, vous devez faire très attention lorsque quelqu'un modifie le fichier, car la transaction peut être annulée et la copie du fichier doit être conservée jusqu'à ce que l'ancienne version ne soit plus visible.
Dans le système où les fichiers sont uniquement ajoutés et supprimés, et où l'accès transactionnel aux fichiers n'est pas un problème, le stockage du système de fichiers sera à mon humble avis le meilleur choix.
la source
Il est généralement préférable de stocker de grands objets BLOB dans une table séparée et de conserver une référence de clé étrangère à l'objet BLOB dans votre table principale. De cette façon, vous pouvez toujours extraire le fichier de la base de données (vous n’avez donc pas besoin de code spécial) et vous évitez les problèmes liés aux dépendances externes à la base de données (synchronisation de la base de données et du système de fichiers, etc.), mais vous n’engagez que de la surcharge si vous vous connectez explicitement à cette table (ou effectuez un appel séparé). 10Mo n'est pas très volumineux, la plupart des bases de données commerciales modernes n'auront pas de problème. La seule raison pour laquelle je stocke un fichier dans le système de fichiers est la réduction de la bande passante de la base de données. Si votre base de données doit mélanger un grand nombre de ces fichiers, vous devrez peut-être fractionner la charge de travail et ne stocker qu'un descripteur de fichier. Ensuite, vous pouvez avoir un appel séparé pour charger le fichier depuis un autre serveur,
la source
Vous pourriez rencontrer certains de ces problèmes:
SELECT *
qui implique la rangée avec le gros blob prend très longtemps, même si vous n’avez pas besoin du blob (Bien sûr, vous devriez faire un select spécifique, mais parfois les applications sont écrites comme ça)Bien sûr, vous bénéficiez également d'avantages:
Personnellement, je ne le fais pas car je trouve les inconvénients beaucoup plus lourds que les avantages. Mais comme indiqué ci-dessus, cela dépend totalement de votre cas d'utilisation, etc.
la source
Certains systèmes de gestion de contenu Enterpirse, tels que SiteCore, utilisent une base de données pour stocker les données de page et une autre base de données pour stocker des fichiers. Ils utilisent MS SQL Server.
la source
Pour la mise en œuvre pratique, voici ce qui peut vous préoccuper:
Bénéfices:
Inconvénients:
la source