2015-03-26 13 views
12

Angenommen, ich entwickle eine mobile App wie Instagram. Benutzer können Bilder vom Server herunterladen und eigene Bilder hochladen. Derzeit speichert der Server alle Bilder (in Wirklichkeit nur kleine Thumbnails) in einer MySQL-Datenbank als BLOBs. Es scheint, dass die gebräuchlichste Methode zum Übertragen von Bildern die Base64-Kodierung ist, die mir zwei Möglichkeiten gibt:MySQL - Base64 vs BLOB

  • Server speichert alle Bilder als BLOBs. Um ein Bild hochzuladen, verschlüsselt es den Client in die Base64-Zeichenfolge und sendet sie dann an den Server. Der Server dekodiert Image BACK in das Binärformat und speichert es als BLOB in der Datenbank. Wenn der Client ein Image anfordert, codiert der Server das Image erneut als Base64-String und sendet es an den Client, der es anschließend zur Anzeige in Binärwerte zurückdecodiert.
  • Der Server speichert alle Bilder als Base64-Zeichenfolgen. Um ein Bild hochzuladen, verschlüsselt es den Client in die Base64-Zeichenfolge und sendet sie an den Server. Der Server führt keine Codierung oder Dekodierung durch, speichert die Zeichenfolge jedoch einfach in der Datenbank. Wenn der Client ein Image anfordert, wird die Base64-Zeichenfolge an den Client zurückgegeben, der sie dann zur Anzeige dekodiert.
  • Option # 1 erfordert deutlich mehr Verarbeitung auf dem Server, da Bilder mit jeder einzelnen Anfrage codiert/decodiert werden müssen. Dies führt mich zu Option 2, aber einige Untersuchungen haben ergeben, dass das Speichern der Base64-Zeichenfolge in MySQL viel weniger effizient ist als das Speichern des Abbilds direkt als BLOB, und im Allgemeinen wird davon abgeraten.

    Ich bin sicherlich nicht die erste Person, die auf diese Situation trifft, also hat jemand Vorschläge für den besten Weg, um dies zu arbeiten?

    +2

    Option # 3 ist keine Bilder in der Datenbank an erster Stelle. Sie haben ein System dafür: Das Dateisystem. – tadman

    +0

    Ich begann mit dem Speichern von Dateipfaden, aber einige Nachforschungen zu den neuesten Versionen von MySQL haben ergeben, dass es tatsächlich effizienter ist, kleine Dateien (unter 1 oder 2 MB) als BLOBs zu speichern. Meine Bilder sind nur ein paar kb, so dass es viel einfacher ist, diesen Weg zu pflegen. – hundley

    +0

    Eine Datenbank voller BLOBs zu sichern ist ein absoluter Albtraum. Es ist teuer, diese zu replizieren, teuer, um sie zu unterstützen, extrem schmerzhaft, um sie wiederherzustellen, und quälend, sie aufzuteilen, wenn sie zu groß werden. Wenn Sie nicht mit unwichtigen Datenmengen zu tun haben, wird dies Sie irgendwann in die Luft jagen. Dateien auf der Festplatte können leicht mit etwas so rudimentär wie 'rsync' repliziert werden. Gleiches gilt nicht für MySQL. – tadman

    Antwort

    5

    JSON nimmt utf8 an und ist daher mit Bildern inkompatibel, sofern sie nicht in irgendeiner Weise codiert sind.

    Base64 ist fast genau 8/6 mal so sperrig wie Binär (BLOB). Man könnte argumentieren, dass es leicht erschwinglich ist. 3000 bytes wird etwa 4000 bytes.

    Jeder sollte können beliebige 8-Bit-Codes akzeptieren, aber nicht jeder tut. Base-64 kann der einfachste und insgesamt beste Kompromiss sein, um nicht mit 8-Bit-Daten umgehen zu müssen.

    Da diese "klein" sind, würde ich sie in einer Tabelle speichern, keine Datei. Ich würde sie jedoch in einer separaten Tabelle und JOIN durch eine geeignete id speichern, wenn Sie sie benötigen. Dadurch können Abfragen, für die das Image nicht benötigt wird, schneller ausgeführt werden, da sie nicht über die BLOBs laufen.

    Technisch gesehen würde TEXT CHARACTER SET ascii COLLATE ascii_bin tun, aber BLOB macht es klarer, dass es wirklich keinen verwendbaren Text in der Spalte gibt.

    +0

    Um zu verdeutlichen, schlagen Sie vor, dass ich die Bilder als Base64 in einem BLOB oder die Binärdaten selbst speichern und bei jedem Abruf codieren? Was deinen Vorschlag mit JOINing betrifft - genau das mache ich, zusammen mit einem Sphinx-Index. – hundley

    +0

    Base64 während seines gesamten Lebens. Dann müssen Sie nicht irgendwo entkommen. Also, ja, Base64 in einem BLOB ohne Enkodierung außer beim ersten INSERT. Das ist meine Meinung_. –

    +0

    Interessant, vielleicht gebe ich das eine Chance. Es würde definitiv eine Menge CPU sparen, da Abrufe viel häufiger als Einfügungen auftreten. – hundley

    1

    Warum würden Sie Base64-kodieren die Bilder auf dem Draht? Ich denke, du starrst von einer falschen Annahme aus.

    +0

    Könnten Sie klären? Im Moment sende ich alle Bilder als Base64-kodierte JSON-Objekte mit einigen Metadaten (so weiß der Client, was mit dem Bild beim Empfang zu tun ist). Gibt es eine Möglichkeit, die Bilder als binäre Objekte (keine Codierung) mit Metadaten zu senden? Was ist mit dem Kunden POST ein neues Bild? Mein Server verwendet Node.js mit Express für HTTP sowie [ws] (https://github.com/websockets/ws) für einige WebSocket-Funktionen. – hundley