Aktualisierung auf 2012, wenn wir sehen, dass die Bildgröße und die Anzahl der Bilder in allen Anwendungen immer größer werden ...
Wir brauchen eine Unterscheidung zwischen "Originalbild" und "verarbeitetem Bild", wie zum Beispiel eine Miniaturansicht.
Wie Jcobys Antwort sagt, gibt es zwei Möglichkeiten, die ich empfehle:
verwenden Blob (Binary Large Object): für Originalbildspeicher, am Tisch. Siehe Iwans Antwort (kein Problem beim Sichern von Blobs!), PostgreSQL-Zusatzmodule , Anleitungen usw.
Verwenden Sie eine separate Datenbank mit DBlink : für den ursprünglichen Bildspeicher in einer anderen (einheitlichen / spezialisierten) Datenbank. In diesem Fall bevorzuge ich Bytea , aber Blob ist fast gleich. Das Trennen der Datenbank ist der beste Weg für einen "einheitlichen Image-Webservice".
Verwenden Sie bytea (BYTE Array): zum Zwischenspeichern von Miniaturbildern. Zwischenspeichern Sie die kleinen Bilder, um sie schnell an den Webbrowser zu senden (um Renderingprobleme zu vermeiden) und die Serververarbeitung zu reduzieren. Cache auch wichtige Metadaten wie Breite und Höhe. Das Zwischenspeichern von Datenbanken ist der einfachste Weg. Überprüfen Sie jedoch Ihre Anforderungen und Serverkonfigurationen (z. B. Apache-Module): Das Speichern von Miniaturansichten im Dateisystem ist möglicherweise besser. Vergleichen Sie die Leistung. Denken Sie daran, dass es sich um einen (einheitlichen) Webdienst handelt, der dann in einer separaten Datenbank (ohne Sicherungen) gespeichert werden kann und viele Tabellen bedient. Siehe auch Handbuch für binäre PostgreSQL-Datentypen , Tests mit Bytea-Spalte usw.
HINWEIS 1: Heute ist die Verwendung von "dualen Lösungen" (Datenbank + Dateisystem) veraltet (!). Die Verwendung von "nur Datenbank" anstelle von "dual" bietet viele Vorteile. PostgreSQL bietet eine vergleichbare Leistung und gute Tools für Export / Import / Eingabe / Ausgabe.
HINWEIS 2: Denken Sie daran, dass PostgreSQL nur Bytea und kein Standard- BLOB von Oracle hat : "Der SQL-Standard definiert (...) BLOB. Das Eingabeformat unterscheidet sich von Bytea, aber die bereitgestellten Funktionen und Operatoren sind größtenteils gleich", Manual .
EDIT 2014 : Ich habe den obigen Originaltext heute nicht geändert (meine Antwort war der 22. April 12, jetzt mit 14 Stimmen). Ich öffne die Antwort für Ihre Änderungen (siehe "Wiki-Modus", können Sie bearbeiten!) Zum Korrekturlesen und für Updates .
Die Frage ist stabil (@ Ivans '08 Antwort mit 19 Stimmen), bitte helfen Sie, diesen Text zu verbessern.
Antwort von Re jcoby:
bytea als "normale" Spalte bedeutet auch, dass der Wert beim Abrufen vollständig in den Speicher eingelesen wird. Im Gegensatz dazu können Sie Blobs in stdout streamen. Dies hilft bei der Reduzierung des Speicherbedarfs des Servers. Besonders, wenn Sie 4-6 MPix-Bilder speichern.
Kein Problem beim Sichern von Blobs. pg_dump bietet die Option "-b", um die großen Objekte in die Sicherung aufzunehmen.
Ich bevorzuge also die Verwendung von pg_lo_ *.
Antwort von Re Kris Erickson:
Ich würde das Gegenteil sagen :). Wenn Bilder nicht die einzigen Daten sind, die Sie speichern, speichern Sie sie nicht im Dateisystem, es sei denn, Sie müssen dies unbedingt tun. Es ist von großem Vorteil, immer sicher zu sein, dass Ihre Daten konsistent sind, und die Daten "in einem Stück" (der DB) zu haben. Übrigens ist PostgreSQL hervorragend geeignet, um die Konsistenz zu erhalten.
Allerdings ist die Realität oft zu leistungsintensiv ;-), und Sie müssen die Binärdateien aus dem Dateisystem bereitstellen. Aber selbst dann neige ich dazu, die Datenbank als "Master" -Speicher für Binärdateien zu verwenden, wobei alle anderen Beziehungen konsistent verknüpft sind, und gleichzeitig einen dateisystembasierten Caching-Mechanismus zur Leistungsoptimierung bereitzustellen.
quelle
BYTEA
eine "normale" Spalte. Postgres unterstützt seit vielen Jahren das Streaming zu / vonBYTEA
Spalten, sodass Sie den Inhalt nicht im Speicher speichern müssen, bevor Sie ihn in der Datenbank speichern.In der Datenbank gibt es zwei Möglichkeiten:
Ich habe in der Vergangenheit mit großem Erfolg Bytea-Spalten verwendet, um mehr als 10 GB Bilder mit Tausenden von Zeilen zu speichern. Die TOAST-Funktionalität von PG negiert so ziemlich jeden Vorteil, den Blobs haben. In beiden Fällen müssen Sie Metadatenspalten für Dateiname, Inhaltstyp, Abmessungen usw. einfügen.
quelle
Schnelles Update bis Mitte 2015:
Sie können die Postgres Foreign Data-Schnittstelle verwenden , um die Dateien in einer geeigneteren Datenbank zu speichern. Legen Sie die Dateien beispielsweise in einem GridFS ab, das Teil von MongoDB ist. Verwenden Sie dann https://github.com/EnterpriseDB/mongo_fdw , um in Postgres darauf zuzugreifen.
Das hat den Vorteil, dass Sie in Postrgres und MongoDB darauf zugreifen / lesen / schreiben / sichern können, je nachdem, was Ihnen mehr Flexibilität gibt.
Es gibt auch fremde Daten-Wrapper für Dateisysteme: https://wiki.postgresql.org/wiki/Foreign_data_wrappers#File_Wrappers
Als Beispiel können Sie dieses verwenden: https://multicorn.readthedocs.org/en/latest/foreign-data-wrappers/fsfdw.html (siehe hier für ein kurzes Anwendungsbeispiel)
Dies gibt Ihnen den Vorteil der Konsistenz (alle verknüpften Dateien sind definitiv vorhanden) und aller anderen ACIDs, während sie sich noch im eigentlichen Dateisystem befinden. Dies bedeutet, dass Sie jedes gewünschte Dateisystem verwenden können und der Webserver sie direkt bereitstellen kann ( OS-Caching gilt auch).
quelle
Update von 10 Jahren später Im Jahr 2008 hatten die Festplatten, auf denen Sie eine Datenbank ausführen würden, sehr unterschiedliche Eigenschaften und viel höhere Kosten als die Festplatten, auf denen Sie Dateien speichern würden. Heutzutage gibt es viel bessere Lösungen zum Speichern von Dateien, die es vor 10 Jahren noch nicht gab, und ich würde diesen Rat widerrufen und den Lesern raten, sich einige der anderen Antworten in diesem Thread anzusehen.
Original
Speichern Sie keine Bilder in der Datenbank, es sei denn, Sie müssen dies unbedingt tun. Ich verstehe, dass dies keine Webanwendung ist, aber wenn es keinen freigegebenen Dateispeicherort gibt, können Sie darauf verweisen, um den Speicherort der Datei in der Datenbank zu speichern.
Dann können Sie vielleicht schnell einen Webserver einrichten und die Web-URLs in der Datenbank (sowie den lokalen Pfad) speichern. Während Datenbanken LOBs und 3000 Bilder (4-6 Megapixel, vorausgesetzt 500 KB pro Bild) verarbeiten können, sind 1,5 Gigs nicht viel Speicherplatz. Dateisysteme sind für das Speichern großer Dateien viel besser geeignet als eine Datenbank.
quelle
Versuchen Sie dies . Ich habe das LOB-Format (Large Object Binary) verwendet, um generierte PDF-Dokumente, von denen einige mehr als 10 MB groß waren, in einer Datenbank zu speichern, und es hat wunderbar funktioniert.
quelle
Wenn Ihre Bilder klein sind, sollten Sie sie als base64 in einem Nur-Text-Feld speichern.
Der Grund dafür ist, dass base64 einen Overhead von 33% hat und die Komprimierung größtenteils wegfällt. (Siehe Wie hoch ist der Speicherplatzaufwand für die Base64-Codierung? ) Ihre Datenbank wird größer, die Pakete, die Ihr Webserver an den Client sendet, jedoch nicht. In HTML können Sie base64 in ein <img src = ""> -Tag einbinden, was möglicherweise Ihre App vereinfachen kann, da Sie die Bilder nicht als Binärdateien in einem separaten Browserabruf bereitstellen müssen. Der Umgang mit Bildern als Text vereinfacht auch das Senden / Empfangen von JSON, was Binärdateien nicht sehr gut handhabt.
Ja, ich verstehe, Sie könnten die Binärdatei in der Datenbank speichern und sie auf dem Weg in und aus der Datenbank in / aus Text konvertieren, aber manchmal machen ORMs dies zu einem Problem. Es kann einfacher sein, es wie alle anderen Felder als geraden Text zu behandeln.
Dies ist definitiv der richtige Weg, um mit Thumbnails umzugehen.
(Die Bilder von OP sind nicht klein, daher ist dies keine wirkliche Antwort auf seine Frage.)
quelle