Bilder im DB speichern – Ja oder Nein?

Also verwende ich eine App, die Bilder stark in der DB speichert. Was ist deine Meinung dazu? Ich bin eher ein Typ, um den Speicherort im Dateisystem zu speichern, als es direkt in der database zu speichern.

Was denkst du sind die Vor- / Nachteile?

Ich bin verantwortlich für einige Anwendungen, die viele TB Bilder verwalten. Wir haben festgestellt, dass das Speichern von Dateipfaden in der database am besten ist.

Es gibt ein paar Probleme:

  • databasespeicher ist normalerweise teurer als Dateisystemspeicher
  • Sie können den Zugriff auf das Dateisystem mit standardmäßigen Standardprodukten beschleunigen
    • Beispielsweise verwenden viele Webserver den Systemaufruf sendfile () des Betriebssystems, um Dateien asynchron direkt vom Dateisystem an die Netzwerkschnittstelle zu senden. Bilder, die in einer database gespeichert sind, profitieren nicht von dieser Optimierung.
  • Dinge wie Webserver usw. benötigen keine spezielle Codierung oder Verarbeitung für den Zugriff auf Bilder im Dateisystem
  • databaseen gewinnen, wo transaktionale Integrität zwischen dem Bild und Metadaten wichtig sind.
    • Es ist komplexer, die Integrität zwischen databasemetadaten und Dateisystemdaten zu verwalten
    • Es ist schwierig (im Kontext einer Web-Anwendung) zu garantieren, dass Daten auf dem Dateisystem auf die Festplatte geschrieben wurden

Wie bei den meisten Problemen ist es nicht so einfach wie es klingt. Es gibt Fälle, in denen es sinnvoll wäre, die Bilder in der database zu speichern.

  • Sie speichern Bilder, die sich dynamisch ändern, Rechnungen sagen und eine Rechnung wie am 1. Januar 2007 erhalten möchten?
  • Die Regierung möchte, dass Sie 6 Jahre Geschichte führen
  • In der database gespeicherte Bilder erfordern keine andere Sicherungsstrategie. Bilder, die im Dateisystem gespeichert sind
  • Es ist einfacher, den Zugriff auf die Bilder zu steuern, wenn sie sich in einer database befinden. Unbefugte Administratoren können auf jeden Ordner auf der Festplatte zugreifen. Es braucht einen wirklich entschlossenen Administrator, in einer database zu suchen, um die Bilder zu extrahieren

Auf der anderen Seite sind Probleme damit verbunden

  • Erfordert zusätzlichen Code zum Extrahieren und Streamen der Bilder
  • Die Latenz kann langsamer sein als der direkte Dateizugriff
  • Schwerere Belastung des databaseservers

Dateispeicher Die Facebook-Ingenieure haben viel darüber geredet. Ein Weg war es, die praktische Grenze von Dateien in einem Verzeichnis zu kennen.

Nadel im Heuhaufen: Effiziente Speicherung von Milliarden Fotos

Das ist vielleicht ein bisschen weit hergeholt, aber wenn Sie SQL Server 2008 verwenden (oder planen, dies zu tun), würde ich Ihnen empfehlen, sich den neuen FileStream- Datentyp anzusehen .

FileStream triggers die meisten Probleme beim Speichern der Dateien in der DB:

  1. Die Blobs werden tatsächlich als Dateien in einem Ordner gespeichert.
  2. Auf die Blobs kann entweder über eine databaseverbindung oder über das Dateisystem zugegriffen werden.
  3. Sicherungen sind integriert.
  4. Migration “funktioniert einfach”.

Die “Transparent Data Encryption” von SQL verschlüsselt jedoch keine FileStream-Objekte. Wenn das eine Überlegung ist, können Sie sie besser als varbinary speichern.

Aus dem MSDN-Artikel:

Transact-SQL-statementen können FILESTREAM-Daten einfügen, aktualisieren, abfragen, durchsuchen und sichern. Win32-Dateisystemschnittstellen bieten Streaming-Zugriff auf die Daten.
FILESTREAM verwendet den NT-Systemcache zum Zwischenspeichern von Dateidaten. Dies verringert die Auswirkungen von FILESTREAM-Daten auf die performance von Database Engine. Der SQL Server-Pufferpool wird nicht verwendet. Daher steht dieser Speicher für die Abfrageverarbeitung zur Verfügung.

Dateipfade in der DB ist definitiv der Weg zu gehen – ich habe Geschichte von Geschichte von Kunden mit TB von Bildern gehört, dass es ein Albtraum wurde, jede bedeutende Menge von Bildern in einer DB zu speichern – der performanceshit allein ist zu viel.

Nach meiner Erfahrung ist es manchmal die einfachste Lösung, die Bilder nach dem Primärschlüssel zu benennen . So ist es einfach, das Bild zu finden, das zu einem bestimmten Datensatz gehört, und umgekehrt. Gleichzeitig speichern Sie jedoch nichts über das Bild in der database.

Der Trick hier ist, kein Eiferer zu werden.

Eine Sache, die hier zu beachten ist, ist, dass niemand im Dateisystem des pro-Dateisystems ein bestimmtes Dateisystem aufgelistet hat. Bedeutet dies, dass alles von FAT16 bis ZFS jede database übertrifft?

Nein.

Die Wahrheit ist, dass viele databaseen viele Dateisysteme excel, selbst wenn wir nur von roher Geschwindigkeit sprechen.

Die richtige Vorgehensweise ist es, die richtige Entscheidung für Ihr genaues Szenario zu treffen. Dazu benötigen Sie einige Zahlen und einige Anwendungsfallschätzungen.

An Orten, an denen Sie die referenzielle Integrität und ACID-Konformität gewährleisten müssen, ist das Speichern von Bildern in der database erforderlich.

Sie können nicht automatisch garantieren, dass sich das Bild und die Metadaten zu diesem Bild in der database auf die gleiche Datei beziehen. Mit anderen Worten, es kann nicht garantiert werden, dass die Datei auf dem Dateisystem immer nur zur gleichen Zeit und in der gleichen Transaktion wie die Metadaten geändert wird.

Wie andere gesagt haben, kommt SQL 2008 mit einem Filestream-Typ, der es ermöglicht, einen Dateinamen oder eine Kennung als pointers in der db zu speichern und das Bild automatisch auf Ihrem Dateisystem zu speichern, was ein großartiges Szenario ist.

Wenn Sie sich in einer älteren database befinden, würde ich sagen, dass Sie, wenn Sie sie als Blobdaten speichern, wirklich nichts aus der database herausholen werden, was die Suche nach functionen betrifft, also ist es wahrscheinlich das Beste um eine Adresse in einem Dateisystem zu speichern und das Bild auf diese Weise zu speichern.

Auf diese Weise sparen Sie auch Speicherplatz in Ihrem Dateisystem, da Sie nur die exakte Menge an Speicherplatz oder sogar komprimierten Speicherplatz im Dateisystem speichern.

Sie können sich auch entscheiden, mit einer Struktur oder Elementen zu speichern, mit denen Sie die Rohbilder in Ihrem Dateisystem ohne databasetreffer durchsuchen oder die Dateien in großen Mengen auf ein anderes System, eine Festplatte, S3 oder ein anderes Szenario übertragen können – den Speicherort aktualisieren Ihr Programm, aber behalten Sie die Struktur, wieder ohne viel von einem Versuch, die Bilder aus Ihrem db zu bringen, wenn Sie versuchen, den Speicher zu erhöhen.

Wahrscheinlich könntest du auch ein Caching-Element basierend auf häufig gefundenen Bild-URLs in deine Web-Engine / dein Programm casting, damit du dich dort auch selbst speicherst.

Kleine statische Bilder (nicht mehr als ein paar MB), die nicht häufig bearbeitet werden, sollten in der database gespeichert werden. Diese Methode hat mehrere Vorteile, einschließlich einfacherer Übertragbarkeit (Bilder werden mit der database übertragen), einfacheres Sichern / Wiederherstellen (Bilder werden mit der database gesichert) und bessere Skalierbarkeit (ein Dateisystemordner mit Tausenden kleiner Miniaturdateien klingt wie ein Albtraum für Skalierbarkeit) mich).

Das Bereitstellen von Images aus einer database ist einfach. Implementieren Sie einfach einen HTTP-Handler, der das vom DB-Server zurückgegebene Byte-Array als binären Stream bereitstellt.

Hier ist ein interessantes Whitepaper zum Thema.

Zu BLOB oder Nicht zu BLOB: Large Object Storage in einer database oder einem Dateisystem

Die Antwort lautet: “Es kommt darauf an.” Sicherlich würde es von dem databaseserver und seinem Ansatz zum Blob-Speicher abhängen. Dies hängt auch von der Art der Daten ab, die in Blobs gespeichert werden, sowie davon, wie auf diese Daten zugegriffen werden soll.

Kleinere Dateien können unter Verwendung der database als Speichermechanismus effizient gespeichert und geliefert werden. Größere Dateien würden wahrscheinlich am besten unter Verwendung des Dateisystems gespeichert, insbesondere wenn sie häufig modifiziert / aktualisiert werden. (Die Blob-Fragmentierung wird zu einem Problem in Bezug auf die performance.)

Hier ist ein weiterer Punkt, den Sie beachten sollten. Einer der Gründe für die Verwendung einer database zum Speichern der Blobs ist die Einhaltung der ACID. Der von den Testern im Whitepaper verwendete Ansatz (Option “Massenprotokollierung” von SQL Server), der den SQL Server-Durchsatz verdoppelte, änderte jedoch effektiv das “D” in ACID in ein “d”, da die Blobdaten nicht protokolliert wurden Das Initial schreibt für die Transaktion. Wenn die vollständige ACID-Konformität eine wichtige Voraussetzung für Ihr System darstellt, sollten Sie daher die SQL Server-Durchsatzzahlen für databaseschreibvorgänge halbieren, wenn Sie Datei-E / A mit database-BLOB-E / A vergleichen.

Eine Sache, die ich bis jetzt noch nicht erwähnt habe, ist jedoch bemerkenswert, dass es Probleme gibt, große Mengen von Bildern in den meisten Dateisystemen zu speichern. Wenn Sie beispielsweise den oben genannten Ansatz wählen und jede Bilddatei nach dem Primärschlüssel benennen, stoßen Sie bei den meisten Dateisystemen auf Probleme, wenn Sie versuchen, alle Bilder in ein großes Verzeichnis zu stellen, sobald Sie eine sehr große Anzahl von Bildern erreicht haben ( zB in Hunderttausenden oder Millionen).

Eine übliche Lösung besteht darin, sie in einem ausgewogenen Verzeichnis von Unterverzeichnissen zusammenzufassen.

Etwas, das niemand erwähnt hat, ist, dass die DB atomare Aktionen, transaktionale Integrität und concurrency garantiert. Auch die referentielle Integrität ist mit einem Dateisystem außerhalb des Fensters – woher wissen Sie, dass Ihre Dateinamen wirklich korrekt sind?

Wenn Sie Ihre Bilder in einem Dateisystem haben und jemand die Datei liest, während Sie eine neue Version schreiben oder sogar die Datei löschen – was passiert?

Wir verwenden Blobs, weil sie einfacher zu verwalten sind (Backup, Replikation, Transfer). Sie arbeiten gut für uns.

Das Problem beim Speichern von Dateipfaden in Bildern in einer database besteht darin, dass die Integrität der database nicht mehr erzwungen werden kann.

Wenn das tatsächliche Bild, auf das der Dateipfad verweist, nicht mehr verfügbar ist, weist die database unwissentlich einen Integritätserrors auf.

Angesichts der Tatsache, dass die Bilder die eigentlichen Daten sind, die gesucht werden, und dass sie leichter verwaltet werden können (die Bilder werden nicht plötzlich verschwinden) in einer integrierten database, anstatt sich mit irgendeiner Art von Dateisystem zu verbinden (wenn auf das Dateisystem unabhängig zugegriffen wird), die Bilder könnten plötzlich “verschwinden”, ich würde sie direkt als BLOB oder ähnliches speichern.

In einer Firma, in der ich früher gearbeitet habe, haben wir 155 Millionen Bilder in einer Oracle 8i (damals 9i) database gespeichert. 7.5TB wert.

Normalerweise bin ich dagegen, den teuersten und härtesten Teil der Infrastruktur (der database) zu skalieren und alles zu laden. Auf der anderen Seite: Es vereinfacht die Backup-Strategie erheblich, besonders wenn Sie mehrere Webserver haben und die Daten irgendwie synchron halten müssen.

Wie die meisten anderen Dinge, hängt es von der erwarteten Größe und Budget.

Wir haben ein Dokumenten-Imaging-System implementiert, das alle seine Bilder in SQL2005-Blob-Feldern speichert. Momentan gibt es mehrere hundert GB und wir sehen hervorragende Antwortzeiten und geringe oder keine performanceseinbußen. Darüber hinaus verfügen wir über eine Middleware-Schicht, die neu veröffentlichte Dokumente in einem optischen Jukebox-System archiviert, das sie als Standard-NTFS-Dateisystem verfügbar macht.

Wir waren sehr zufrieden mit den Ergebnissen, insbesondere in Bezug auf:

  1. Einfache Replikation und Backup
  2. Möglichkeit, ein Dokumentversionssystem einfach zu implementieren

Wenn es sich um eine webbasierte Anwendung handelt, kann es vorteilhaft sein, die Bilder in einem Speicherliefernetzwerk eines Drittanbieters wie Amazon S3 oder der Nirvanix-Plattform zu speichern.

Annahme: Die Anwendung ist webfähig / webbasiert

Ich bin überrascht, dass niemand dies wirklich erwähnt hat … delegiere es an andere, die Spezialisten sind -> nutze einen Image- / Filehosting-Provider von Drittanbietern .

Speichern Sie Ihre Dateien auf einem kostenpflichtigen Online-Dienst wie

  • Amazon S3
  • Moso Cloud Speicher

Ein anderer StackOverflow Thread redet hierüber.

Dieser Thread erklärt, warum Sie einen Drittanbieter-Hosting-Provider verwenden sollten.

Es ist es so wert. Sie speichern es effizient. Es wird keine Bandbreite von Ihren Servern auf Client-Anfragen hochgeladen usw.

Wenn Sie nicht mit SQL Server 2008 arbeiten und gute Gründe dafür haben, bestimmte Image-Dateien in der database zu speichern, können Sie den Ansatz “Beide” verwenden und das Dateisystem als temporären Cache verwenden und die database als Master-Repository verwenden .

Ihre Geschäftslogik kann z. B. prüfen, ob eine Image-Datei auf der Disc vorhanden ist, bevor sie sie ausliefert, und bei Bedarf aus der database abrufen. Auf diese Weise können Sie mehrere Webserver und weniger Synchronisierungsprobleme beheben.

Ich bin nicht sicher, wie viel von einem “realen” Beispiel dies ist, aber ich habe derzeit eine Anwendung, die Details für ein Sammelkartenspiel speichert, einschließlich der Bilder für die Karten. Zugegeben, die Rekordzahl für die database beträgt nur 2851 Datensätze bis heute, aber angesichts der Tatsache, dass bestimmte Karten mehrfach veröffentlicht wurden und alternatives Artwork haben, war es tatsächlich effizienter, das “primäre Quadrat” des Artworks und dann dynamisch zu scannen generiere die Grenze und verschiedene Effekte für die Karte, wenn sie angefordert werden.

Der ursprüngliche Ersteller dieser Bildbibliothek hat eine Datenzugriffsklasse erstellt, die das Bild basierend auf der Anforderung rendert, und es ist ziemlich schnell zum Anzeigen und für einzelne Karten.

Dies erleichtert auch die Bereitstellung / Updates, wenn neue Karten veröffentlicht werden, anstatt einen ganzen Ordner mit Bildern zu verschneiden und diese in die Pipe zu schicken und sicherzustellen, dass die richtige Ordnerstruktur erstellt wird. Ich aktualisiere einfach die database und lasse sie erneut herunterladen. Die Größe beträgt derzeit 56 MB, was nicht gut ist, aber ich arbeite an einer inkrementellen Update-function für zukünftige Versionen. Darüber hinaus gibt es eine “keine Bilder” -Version der Anwendung, die es den Benutzern ermöglicht, die Anwendung ohne Download-Verzögerung zu erhalten.

Diese Lösung hat sich bewährt, da die Anwendung selbst als einzelne Instanz auf dem Desktop ausgeführt wird. Es gibt eine Website, wo all diese Daten für den Online-Zugriff archiviert werden, aber ich würde in keiner Weise die gleiche Lösung dafür verwenden. Ich stimme zu, dass der Dateizugriff vorzuziehen wäre, weil er besser auf die Häufigkeit und das Volumen der Anforderungen abgestimmt würde, die für die Bilder gestellt werden.

Hoffentlich ist das nicht zu viel Geplapper, aber ich sah das Thema und wollte einige meiner Einsichten aus einer relativ erfolgreichen kleinen / mittleren Anwendung liefern.

SQL Server 2008 bietet eine Lösung, die das Beste aus beiden Welten bietet: den Filestream-Datentyp .

Verwalten Sie es wie eine normale Tabelle und haben Sie die performance des Dateisystems.

Es hängt von der Anzahl der Bilder ab, die Sie speichern werden, und auch von deren Größe. Ich habe databaseen verwendet, um Bilder in der Vergangenheit zu speichern, und meine Erfahrung war ziemlich gut.

IMO, Vorteile der Verwendung der database zum Speichern von Bildern sind,

A. Sie benötigen keine FS-Struktur, um Ihre Bilder zu halten
B. databaseindizes sind besser als FS-Bäume, wenn mehr Artikel gespeichert werden sollen
C. Eine intelligent abgestimmte database führt beim Zwischenspeichern der Abfrageergebnisse eine gute Arbeit durch
D. Backups sind einfach. Es funktioniert auch gut, wenn Sie die Replikation eingerichtet haben und der Inhalt von einem Server in der Nähe des Benutzers geliefert wird. In solchen Fällen ist keine explizite Synchronisation erforderlich.

Wenn Ihre Bilder klein sind (sagen wir <64k) und die Speicher-Engine Ihrer Datenbank Inline-BLOBs unterstützt, verbessert dies die Leistung weiter, da keine Indirektion erforderlich ist (Lokalität der Referenz wird erreicht).

Das Speichern von Bildern kann eine schlechte Idee sein, wenn Sie mit einer kleinen Anzahl von Bildern großer Größe arbeiten. Ein weiteres Problem beim Speichern von Bildern in db besteht darin, dass Metadaten wie Erstellungs- und Änderungsdaten von Ihrer Anwendung verarbeitet werden müssen.

Ich habe vor kurzem eine PHP / MySQL-App erstellt, die PDFs / Word-Dateien in einer MySQL-Tabelle (so groß wie 40 MB pro Datei) speichert.

Vorteile:

  • Hochgeladene Dateien werden zusammen mit allem anderen auf den Backup-Server repliziert. Es ist keine separate Backup-Strategie erforderlich (Sorgenfreiheit).
  • Das Einrichten des Webservers ist etwas einfacher, da ich keinen uploads / Ordner benötige und allen meinen Anwendungen mitteilen muss, wo sie sich befinden.
  • Ich kann Transaktionen zur Bearbeitung verwenden, um die Datenintegrität zu verbessern – ich muss mich nicht um verwaiste und fehlende Dateien kümmern

Nachteile:

  • mysqldump benötigt jetzt eine sehr lange Zeit, da sich in einer der Tabellen 500 MB Daten befinden.
  • Insgesamt nicht sehr Speicher / CPU im Vergleich zu Dateisystem

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

Nach meiner Erfahrung musste ich beide Situationen verwalten: Bilder in der database und Bilder im Dateisystem mit Pfad in db gespeichert.

Die erste Lösung, Bilder in der database, ist etwas “sauberer”, da Ihre Datenzugriffsebene nur mit databaseobjekten arbeiten muss; aber das ist nur gut, wenn Sie mit niedrigen Zahlen umgehen müssen.

Offensichtlich verschlechtert sich die Performance des databasezugriffs, wenn Sie mit binären großen Objekten arbeiten, und die databasedimensionen werden stark anwachsen, was wiederum zu performanceseinbußen führt … und normalerweise ist databasespeicher viel teurer als Dateisystemspeicher.

Wenn Sie jedoch große binäre Objekte im Dateisystem gespeichert haben, haben Sie Backup-Pläne, die sowohl die database als auch das Dateisystem berücksichtigen müssen. Dies kann für einige Systeme ein Problem darstellen.

Ein weiterer Grund für ein Dateisystem ist, wenn Sie Ihre Bilddaten (oder Sounds, Videos, was auch immer) mit dem Zugriff Dritter teilen müssen: In diesen Tagen entwickle ich eine Web-App, die Bilder verwendet, auf die von “draußen” zugegriffen werden muss “Meine Webfarm so, dass ein databasezugriff zum Abrufen von Binärdaten einfach unmöglich ist. Manchmal gibt es auch Design-Überlegungen, die Sie zu einer Entscheidung führen.

Berücksichtigen Sie bei dieser Wahl auch, ob Sie beim Zugriff auf binäre Objekte mit Berechtigung und Authentifizierung umgehen müssen: Diese Anforderungen können normalerweise einfacher getriggers werden, wenn Daten in db gespeichert werden.

Ich habe einmal an einer Bildbearbeitungsanwendung gearbeitet. Wir speicherten die hochgeladenen Bilder in einem Verzeichnis, das etwa / images / [heutiges Datum] / [ID-Nummer] war. Aber wir extrahierten auch die Metadaten (Exif-Daten) aus den Bildern und speicherten diese in der database zusammen mit einem Zeitstempel und dergleichen.

In einem früheren Projekt habe ich Bilder auf dem Dateisystem gespeichert, und das hat bei Backups, Replikation und der Synchronisation des Dateisystems mit der database viel Kopfzerbrechen bereitet.

In meinem neuesten Projekt speichere ich Bilder in der database und speichere sie im Dateisystem, und es funktioniert wirklich gut. Ich hatte bisher keine Probleme.

Zweitens die Empfehlung zu Dateipfaden. Ich habe an einigen Projekten gearbeitet, die umfangreiche Asset-Sammlungen verwalten mussten, und alle Versuche, Dinge direkt in der database zu speichern, führten langfristig zu Schmerzen und Frustration.

Der einzige wirkliche “Profi”, den ich mir vorstellen kann, wenn man sie in der database speichert, ist die Möglichkeit, einzelne Bild-Assets zu vereinfachen. Wenn keine Dateipfade verwendet werden und alle Bilder direkt aus der DB gestreamt werden, besteht keine Gefahr, dass Benutzer Dateien finden, auf die sie keinen Zugriff haben sollten.

Das scheint besser mit einem intermediären Skript zu lösen, das Daten aus einem webunabhängigen Dateispeicher zieht. Daher ist der DB-Speicher NICHT WIRKLICH notwendig.

Das Wort auf der Straße ist, dass, wenn Sie nicht ein database-Anbieter versuchen, zu beweisen, dass Ihre database es tun kann (wie sagen wir Microsoft prahlte über Terrasererver speichert eine Bajillion Bilder in SQL Server) es ist keine sehr gute Idee. Wenn die Alternative – Speichern von Bildern auf Dateiservern und Pfaden in der database ist so viel einfacher, warum kümmern? Blob-Felder sind so etwas wie die Off-Road-Fähigkeiten von SUVs – die meisten Leute benutzen sie nicht, diejenigen, die normalerweise in Schwierigkeiten geraten, und dann gibt es diejenigen, die das tun, aber nur zum Spaß.

Wenn Sie ein Bild in der database speichern, bedeutet das, dass die Bilddaten irgendwo im Dateisystem landen, aber verdeckt sind, so dass Sie nicht direkt darauf zugreifen können.

+ ves:

  • databaseintegrität
  • Es ist leicht zu verwalten, da Sie sich nicht darum kümmern müssen, das Dateisystem synchron zu halten, wenn ein Bild hinzugefügt oder gelöscht wird

-ves:

  • performanceseinbußen – Ein database-Lookup ist normalerweise langsamer als ein Dateisystem-Lookup
  • Sie können das Bild nicht direkt bearbeiten (zuschneiden, skalieren)

Beide Methoden sind üblich und werden geübt. Sehen Sie sich die Vor- und Nachteile an. In jedem Fall müssen Sie darüber nachdenken, wie Sie die Nachteile überwinden können. Das Speichern in der database bedeutet in der Regel, databaseparameter zu optimieren und eine Art Caching zu implementieren. Die Verwendung von Dateisystem erfordert, dass Sie eine Möglichkeit finden, Dateisystem + database synchron zu halten.