Was ist der beste Ort zum Speichern hochgeladener Bilder, einer SQL-Datenbank oder eines Datenträger-Dateisystems?

146

Ich schreibe eine Anwendung, mit der Benutzer Bilder auf den Server hochladen können. Ich erwarte ungefähr 20 Bilder pro Tag, alle JPEG und wahrscheinlich nicht bearbeitet / in der Größe geändert. (Dies ist eine weitere Frage, wie die Größe der Bilder auf der Serverseite vor dem Speichern geändert werden kann. Vielleicht kann jemand eine .NET-Ressource dafür im Kommentar oder so ablegen.) Ich frage mich jetzt, wo der beste Ort zum Speichern hochgeladener Bilder ist.

  • Speichern Sie die Bilder als Datei im Dateisystem und erstellen Sie einen Datensatz in einer Tabelle mit dem genauen Pfad zu diesem Bild.

  • Oder speichern Sie das Bild selbst in einer Tabelle unter Verwendung eines Datentyps "Bild" oder "Binärdaten" des Datenbankservers.

Ich sehe in beiden Vor- und Nachteile. Ich mag a), weil ich die Dateien leicht verschieben kann und nur den Tabelleneintrag ändern muss. Andererseits mag ich es nicht, Geschäftsdaten auf dem Webserver zu speichern, und ich möchte den Webserver nicht wirklich mit einer anderen Datenquelle verbinden, die Geschäftsdaten enthält (aus Sicherheitsgründen). Ich mag b), weil alle Informationen sind an einem Ort und leicht zugänglich durch eine Abfrage. Andererseits wird die Datenbank sehr bald sehr groß. Das Auslagern dieser Daten könnte schwieriger sein.

Tobias
quelle
2
Ich habe es nicht gefunden, wo?
Tobias
Mögliches Duplikat des Speicherns von Bildern in DB - Ja oder Nein?
Liam

Antworten:

95

Ich speichere normalerweise Dateien im Dateisystem, da es dafür da ist, obwohl es Ausnahmen gibt. Für Dateien ist das Dateisystem (normalerweise) die flexibelste und leistungsfähigste Lösung.

Es gibt einige Probleme beim Speichern von Dateien in einer Datenbank - Dateien sind im Allgemeinen viel größer als Ihre durchschnittliche Zeile - Ergebnismengen, die viele große Dateien enthalten, verbrauchen viel Speicher. Wenn Sie eine Speicher-Engine verwenden, die Tabellensperren für Schreibvorgänge verwendet (z. B. ISAM), wird Ihre Dateitabelle möglicherweise abhängig von der Größe / Rate der Dateien, die Sie dort speichern, häufig gesperrt.

In Bezug auf die Sicherheit - Normalerweise speichere ich die Dateien in einem Verzeichnis außerhalb des Dokumentstamms (nicht über eine http-Anforderung zugänglich) und stelle sie über ein Skript bereit, das zuerst nach der richtigen Autorisierung sucht.

Eran Galperin
quelle
7
Könnten Sie mir bitte den letzten Absatz (in Bezug auf die Sicherheit) in Bezug auf die technischen Details erläutern, oder Hinweise wären sehr hilfreich. Danke dir.
VishwaKumar
39
(Für alle Googler da draußen) Wenn Sie das Stammverzeichnis Ihrer Site für einen "öffentlichen" Ordner konfiguriert haben (wie in my_website / public / anstelle von nur my_website /), können Sie die Bilder zusammen mit dem Rest im Ordner my_website / my_images speichern Ihre App. Dann würden Ihre img-Tags auf "my_website / image.php? Img_id = 55" anstatt auf "my_website / avatar.png" verweisen, und Ihr image.php-Skript würde nach Überprüfung Ihrer Anmeldeinformationen und Analyse der von Ihnen übergebenen ID die tatsächliche zurückgeben Bild. Auf diese Weise kann das Bild nur von dem ordnungsgemäß angemeldeten Benutzer angezeigt werden.
Kapitän Hypertext
8
Hey Kapitän, Sie sollten das in eine tatsächliche Antwort verwandeln, damit Sie Punkte bekommen können. $$$
Andrew
4
Bitte fügen Sie ein paar weitere Hinweise zur Sicherheit hinzu / verhindern Sie, dass Dateien Ihre Website zerstören
Andrew
1
Dies würde sich nicht skalieren lassen, da die Anzahl der Dateien im Ordner begrenzt ist. Wenn Sie Ihre Dateien in mehrere Ordner aufteilen möchten, würde dies die Komplexität der Indizierung der Dateien erhöhen (um festzustellen, wo die Datei tatsächlich gespeichert ist). Darüber hinaus wird die Suche sehr langsam sein.
Hardik
43

Der einzige Vorteil für die Option B besteht darin, alle Daten in einem System zu haben, aber es ist ein falscher Vorteil! Sie können argumentieren, dass Ihr Code auch eine Form von Daten ist und daher auch in einer Datenbank gespeichert werden kann - wie würde es Ihnen gefallen?

Es sei denn, Sie haben einen Einzelfall:

  • Geschäftslogik gehört in Code.
  • Strukturierte Daten gehören in die Datenbank (relational oder nicht relational).
  • Massendaten gehören in den Speicher (Dateisystem oder andere).

Dateien, Code, Daten

Es ist nicht erforderlich, ein Dateisystem zu verwenden, um Dateien zu speichern. Stattdessen können Sie Cloud-Speicher (wie Amazon S3 ) oder Infrastructure-as-a-Service (wie Uploadcare ) verwenden:

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

Das Speichern von Dateien in der Datenbank ist jedoch eine schlechte Idee.

David Avsajanishvili
quelle
23

Flickr verwendet das Dateisystem - sie diskutieren die Gründe hier

Martin Beckett
quelle
14

Ich weiß, dass dies ein alter Beitrag ist. Aber viele Besucher dieser Seite bekommen nichts mit der Frage zu tun. Besonders für einen Neuling.

So laden Sie Bilder oder Dateien auf unserer Website hoch und speichern sie:

Für eine statische Website gibt es möglicherweise kein Problem, da der Dateispeicher für einige Share-Hosting noch ausreichend ist. Das Problem kommt von einer dynamischen Website, wenn sie größer wird. Größer in der Datenbank kann behandelt werden, aber größere Dateien wie Bilder werden zu einem Problem. Es gibt zwei Arten von Bildern auf einer Website:

  1. Die Bilder stammen vom Administrator für ein dynamisches Blog. Normalerweise wurden diese Bilder vor dem Hochladen optimiert.

  2. Bilder von Benutzern im Falle von Benutzern dürfen Bilder wie Avatar hochladen. Oder Benutzer können Blog-Inhalte erstellen und einige Bilder aus dem Texteditor einfügen. Diese Art von Bildern ist schwer vorherzusagen. Benutzer können große Bilder nur für kleine Inhalte hochladen, indem sie die Größe der Ansicht ändern, jedoch nicht die Größe der Bilder.

Durch Ignorieren von Artikel-Nr. 1 oben, schnelle Lösung für Artikel-Nr. 2 kann vorübergehend durch die folgenden Tipps gelöst werden, wenn unsere Website keine Bildoptimierungsfunktion bietet:

  1. Erlauben Sie Benutzern nicht, direkt aus dem Texteditor hochzuladen, indem Sie sie in die Bildergalerie umleiten. Auf dieser Seite müssen Benutzer Dateien im Voraus hochladen, bevor sie in den Inhalt eingebettet werden können. Diese Methode wird als Dateimanager bezeichnet.

  2. Verwenden Sie eine Zuschneidebildfunktion, damit Benutzer Bilder hochladen können. Dies begrenzt die Bildgröße, selbst wenn Benutzer sehr große Dateien hochladen. Das endgültige Bild ist das Ergebnis des zugeschnittenen Bildes. Wir können die Größe auf der Serverseite definieren und nur beispielsweise 500 KB oder weniger akzeptieren.

Das ist nur vorübergehend. Zur endgültigen Lösung wird die Frage wiederholt:

  • Wie gehe ich mit einem großen Bildspeicher um?
  • Ändern Sie die Größe oder ändern Sie die Erweiterung.
  • Wie geht eine große oder mittlere Website oder ein E-Commerce mit dem Dateispeicher für ihre Bilder um?

Was wir dann tun können:

  1. Migrieren Sie von Share Hosting VPS. Nicht genug? Dann höher durch Upgrade auf Dedicated.

  2. Erstellen Sie Ihren eigenen Server für die Dateispeicherung. Googeln, um es zu tun. Das ist nicht so schwierig wie du denkst. Einige Leute tun es für ihre Website.

  3. Der einfache Weg ist die Verwendung des CDN-Dateispeicherdienstes.

Okay, 1 und 2 sind etwas teuer. Aber nein 3 ist meiner Meinung nach die beste Lösung.

Bei einigen CDN-Diensten können Sie so viele Webdateien speichern, wie Sie möchten.

Frage: "Wie lade ich eine Datei von unserer Website auf CDN hoch?"

Keine Sorge, sobald Sie sich registriert haben, erhalten Sie in der Regel kostenlos Anleitungen zum Hochladen von Dateien und zum Abrufen des Links von / zu Ihrer Website. Sie erhalten eine API und mehr. Es ist einfach.

Einige Anbieter bieten uns einen kostenlosen Service für 14 Tage mit begrenztem Speicher und begrenzter Bandbreite. Aber das wird für den Ausgangspunkt in Ordnung sein. Das einzige Problem ist, dass "die Leute es nie versuchen".

Hoffe, es wird für Anfänger helfen.

Sulung Nugroho
quelle
13

Wir hatten Kunden, die einige Male auf Option B (Datenbankspeicher) in einigen verschiedenen Backends bestanden, und wir sind schließlich immer wieder zu Option A (Dateisystemspeicher) zurückgekehrt.

Solche großen BLOBs wurden selbst von SQL Server 2005, dem neuesten, an dem wir es ausprobiert haben, einfach nicht gut genug gehandhabt.

Insbesondere haben wir ernsthaftes Aufblähen gesehen und ich denke, vielleicht Probleme beim Sperren.

Ein weiterer Hinweis: Wenn Sie NTFS-basierten Speicher (Windows Server usw.) verwenden, sollten Sie einen Weg finden, um Tausende und Abertausende von Dateien in einem Verzeichnis abzulegen. Ich bin mir nicht sicher warum, aber manchmal kommt das Dateisystem mit dieser Situation nicht gut zurecht. Wenn jemand mehr darüber weiß, würde ich es gerne hören.

Aber ich versuche immer, Unterverzeichnisse zu verwenden, um die Dinge ein bisschen aufzubrechen. Das Erstellungsdatum funktioniert oft gut dafür:

Images / 2008/12/17 / .jpg

... Dies bietet ein angemessenes Maß an Trennung und hilft auch beim Debuggen. Explorer- und FTP-Clients können gleichermaßen ersticken, wenn es wirklich große Verzeichnisse gibt.

BEARBEITEN: Nur eine kurze Anmerkung für 2017: In neueren Versionen von SQL Server gibt es neue Optionen für die Behandlung vieler BLOBs, mit denen die von mir diskutierten Nachteile vermieden werden sollen.

BEARBEITEN: Kurznotiz für 2020: Blob-Speicher in AWS / Azure / etc ist seit Jahren ebenfalls eine Option. Dies eignet sich hervorragend für viele webbasierte Projekte, da es billig ist und häufig bestimmte Probleme im Zusammenhang mit der Bereitstellung, der Skalierung auf mehrere Server, dem Debuggen anderer Umgebungen bei Bedarf usw. vereinfacht.

Brian MacKay
quelle
4
Gute Warnung zur Anzahl der Dateien im selben Verzeichnis. Es kann zu Fehlern kommen, die in einer Produktionsumgebung zu schwer zu finden sind.
digao_mb
1
Ich hatte dieses Problem schon einmal getroffen. NTFS verhielt sich mit etwa 10.000 Dateien in einem Ordner unvorhersehbar.
Faiz
1
Nicht nur NTFS, sondern auch BTRFS, das auch Probleme mit großen Mengen von Bildern in einem Ordner hat. Wenn Sie es versuchen lswürden, würde es ewig dauern (hängt). Oder löschen.
Sunapi386
11

Ich habe kürzlich eine PHP / MySQL-App erstellt, die PDFs / Word-Dateien in einer MySQL-Tabelle speichert (bis zu 40 MB pro Datei).

Vorteile:

  • Hochgeladene Dateien werden zusammen mit allem anderen auf den Sicherungsserver repliziert. Es ist keine separate Sicherungsstrategie erforderlich (beruhigend).
  • Das Einrichten des Webservers ist etwas einfacher, da ich keinen Upload / Ordner benötigen und allen meinen Anwendungen mitteilen muss, wo er sich befindet.
  • Ich kann Transaktionen für Bearbeitungen verwenden, um die Datenintegrität zu verbessern - ich muss mich nicht um verwaiste und fehlende Dateien kümmern

Nachteile:

  • mysqldump nimmt jetzt eine lange Zeit in Anspruch, da sich in einer der Tabellen 500 MB Dateidaten befinden.
  • Insgesamt nicht sehr speicher- / CPU-effizient im Vergleich zum Dateisystem

Ich würde meine Implementierung als Erfolg bezeichnen, sie kümmert sich um die Backup-Anforderungen und vereinfacht das Layout des Projekts. Die Leistung ist gut für die 20-30 Personen, die die App verwenden.

zu viel php
quelle
6

Ich verwende hochgeladene Bilder auf meiner Website und würde definitiv Option a) sagen.

Eine andere Sache, die ich wärmstens empfehlen würde, ist die sofortige Änderung des Dateinamens von dem, was der Benutzer das Foto benannt hat, in etwas Verwaltbareres. Zum Beispiel etwas mit Datum und Uhrzeit, um jedes Bild eindeutig zu identifizieren.

Es ist auch hilfreich, den Dateinamen des Benutzers von seltsamen Zeichen zu befreien, um zukünftige Komplikationen zu vermeiden.

Barfoon
quelle
6

Ändern Sie auf jeden Fall die Größe des Bildes und überprüfen Sie das Format, wenn Sie können. Es gab Fälle, in denen schädliche Dateien von unwissenden Hosts hochgeladen und bereitgestellt wurden, beispielsweise von GIFAR Sicherheitsanfälligkeit, ein bösartiges Java-Applet in einer GIF-Datei zu verbergen, das dann Cookies im aktuellen Kontext lesen und an diese senden konnte eine andere Site für einen Cross-Site-Scripting-Angriff. Das Ändern der Größe der Bilder verhindert dies normalerweise, da der eingebettete Code dadurch gestört wird. Während dieser Angriff durch JVM-Patches behoben wurde, können Sie durch das naive Bereitstellen von Binärdateien ohne deren Bereinigung eine ganze Reihe von Sicherheitslücken schließen.

Denken Sie daran, dass die meisten Virenscanner nur gegen das Dateisystem ausgeführt werden können. Wenn Sie Ihre Binärdateien in der Datenbank speichern, können Sie einen Scanner nicht einfach gegen sie ausführen.

Tim Howland
quelle
4

In SQL Server 2008 gibt es einen hybriden Ansatz namens Filestream-Datentyp , über den in RunAs Radio Nr. 74 gesprochen wurde. Er ähnelt dem Besten aus beiden Welten. Die meisten Leute haben die Otion 2008 nicht, aber wenn Sie das tun, sieht diese Option ziemlich cool aus

Charles Graham
quelle
4

Das mache ich im Grunde.

  1. Speichern Sie ein hochgeladenes Bild in einem temporären Verzeichnis oder Speicher.
  2. Verarbeiten Sie das Bild, bevor Sie es dauerhaft speichern. 2.1. Farbkorrekturen 2.2. Komprimieren 2.3. Erstellen Sie mehrere Kopien basierend auf den Bildabmessungen. 2.4. Benennen Sie mit den Suffixen .xl, .lg, .md, .sm usw. um
  3. Packen Sie alle verarbeiteten Bilddateien (aus einer einzelnen Datei) in einen Ordner mit dem Ordnernamen, idder in der Datenbank für jede Zeile / jedes Dokument zusammen mit image file name(oder einem zufälligen Namen als Bildnamen) gespeichert wird .
  4. Erstellen Sie den path Ordner JJJJ / MM / TT, falls nicht vorhanden. Zum Beispiel 21.08.2016. Merken Sie sich diesen Pfad und speichern Sie ihn in der Datenbank für dasselbe Dokument und dieselbe Zeile.
  5. Verschieben Sie den idBildordner in den pathOrdner. (Der Pfadordner befindet sich möglicherweise im Ordner / var / web-content.)
  6. Leeren Sie den Speicherpuffer oder löschen Sie die temporäre Datei.

Wenn Sie auf ein in einem Dokument erwähntes Bild zugreifen müssen, haben Sie den Pfad und die ID des Ordners, der Bilder enthält. Beispielsweise/var/web-content/{{path}}/{{id}}/image-file-name.sm.jpg

Wenn Sie auf diese Weise alle verarbeiteten Bilddateien löschen müssen, löschen Sie einfach den Ordner und seinen Inhalt rekursiv.

Uday Hiwarale
quelle
3

Die meisten Implementierungen sind Option A.

Mit Option B öffnen Sie eine ganze große Dose whoop4ss, wenn Sie diese Bits aus der Datenbank in etwas zusammenfassen, das in einem Browser angezeigt werden kann ... Auch wenn die Datenbank nicht verfügbar ist, sind die Bilder nicht verfügbar.

Ich denke nicht, dass Speicherplatz ein zu großes Problem ist ... Terabyte-Laufwerke kosten jetzt ein paar hundert Dollar.

Wir implementieren mit Option A, weil wir nicht die Zeit oder die Ressourcen haben, um Option B auszuführen.

mson
quelle
3

Versuchen Sie für die automatische Größenänderung imagemagick ... es wird für viele große Open Source-Content- / Fotoverwaltungssysteme verwendet ... und ich glaube, dass es einige .net-Erweiterungen dafür gibt.

jle
quelle
2

Wir verwenden A. Ich würde es auf ein freigegebenes Laufwerk stellen (es sei denn, Sie planen nicht, mehr als einen Server auszuführen).

Wenn die Zeit kommt, in der dies für Sie nicht skalierbar ist, können Sie die Caching-Mechanismen untersuchen.

csexton
quelle
2

Absolut positiv Option A. Andere haben erwähnt, dass Datenbanken im Allgemeinen nicht gut mit BLOBs umgehen, unabhängig davon, ob sie dafür ausgelegt sind oder nicht. Dateisysteme hingegen leben für dieses Zeug. Sie haben die Möglichkeit, RAID-Striping zu verwenden, Bilder auf mehrere Laufwerke zu verteilen und sie sogar auf geografisch unterschiedliche Server zu verteilen.

Ein weiterer Vorteil ist, dass Ihre Datenbanksicherungen / -replikationen ungeheuerlich wären.

dj_segfault
quelle
2

Aus Sicherheitsgründen empfiehlt es sich auch, Probleme zu vermeiden, die durch das Content Sniffing des IE verursacht werden. Dadurch können Angreifer JavaScript in Bilddateien hochladen, die möglicherweise im Kontext Ihrer Website ausgeführt werden. Vielleicht möchten Sie die Bilder vor dem Speichern irgendwie transformieren (zuschneiden / in der Größe ändern), um diese Art von Angriff zu verhindern. Diese Antwort hat einige andere Ideen.

Tag
quelle
2

Nun, ich habe ein ähnliches Projekt, bei dem Benutzer Dateien auf den Server hochladen. Aus meiner Sicht ist Option a) die beste Lösung, da sie flexibler ist. Sie müssen Bilder in einem geschützten Ordner speichern, der nach Unterverzeichnissen klassifiziert ist. Das Hauptverzeichnis muss vom Administrator eingerichtet werden, da der Inhalt keine Skripte ausführen darf (sehr wichtig) und (Lesen, Schreiben) geschützt sein darf, damit er in http-Anforderungen nicht zugänglich ist.

Ich hoffe das hilft dir.

domoindal
quelle
1

Wenn es sich um kleine Dateien handelt, die nicht bearbeitet werden müssen, ist Option B keine schlechte Option. Ich ziehe es vor, Logik zu schreiben, um Dateien zu speichern und verrückte Probleme mit der Verzeichnisstruktur zu lösen. Es ist schlecht, viele Dateien in einem Verzeichnis zu haben. Emkay?

Wenn die Dateien groß sind oder ständig bearbeitet werden müssen, insbesondere von Programmen wie Office, ist Option A die beste Wahl.

In den meisten Fällen ist dies eine Frage der Präferenz, aber wenn Sie Option A wählen, stellen Sie einfach sicher, dass die Verzeichnisse nicht zu viele Dateien enthalten. Wenn Sie Option B auswählen, stellen Sie sicher, dass sich die Tabelle mit den BLOB-Daten in einer eigenen Datenbank und / oder Dateigruppe befindet. Dies hilft bei der Wartung, insbesondere bei Sicherungen / Wiederherstellungen. Ihre regulären Daten sind wahrscheinlich ziemlich klein, während Ihre Bilddaten im Laufe der Zeit sehr groß sein werden.

Charles Graham
quelle
1

Dies hängt von Ihren Anforderungen ab, insbesondere von Volumen, Benutzern und Häufigkeit der Suche. Für kleine oder mittlere Büros ist es jedoch am besten, eine Anwendung wie Apple Photos oder Adobe Lighroom zu verwenden. Sie sind darauf spezialisiert, diese Art von Ressourcen zu speichern, zu katalogisieren, zu indizieren und zu organisieren. Für große Unternehmen mit hohen Speicheranforderungen und einer hohen Anzahl von Benutzern wird jedoch empfohlen, eine Content Management-Plattform mit einem Digital Asset Management wie Nuxeo oder Alfresco zu instanziieren. Beide Angebote, sehr gute Ressourcen, verwalten sehr große Datenmengen mit vereinfachten Methoden, um sie abzurufen. Und sehr wichtig: Für beide Plattformen gibt es eine kostenlose (Open Source) Option.

Carlos Camargo
quelle