2012-03-15 2 views
36

Il metodo comune per memorizzare le immagini in un database è convertire l'immagine in dati base64 prima di memorizzare i dati. Questo processo aumenterà le dimensioni del 33%. In alternativa è possibile memorizzare direttamente l'immagine come BLOB; ad esempio:Memorizzare l'immagine nel database direttamente o come dati base64?

$image = new Imagick("image.jpg"); 
$data = $image->getImageBlob(); 
$data = $mysqli->real_escape_string($data); 
$mysqli->query("INSERT INTO images (data) VALUES ('$data')"); 

e quindi visualizzare l'immagine con

<img src="data:image/jpeg;base64,' . base64_encode($data) . '" /> 

Con quest'ultimo metodo, si salva 1/3 spazio. Perché è più comune memorizzare le immagini come base64 nei database MySQL?

AGGIORNAMENTO: Ci sono molti dibattiti su vantaggi e svantaggi dell'archiviazione di immagini nei database e la maggior parte delle persone ritiene che non sia un approccio pratico. Ad ogni modo, qui presumo che memorizziamo l'immagine nel database e discutiamo il metodo migliore per farlo.

+5

Salvare i dati in un file e memorizzare solo il percorso del file o l'url nel database – Fredrik

+0

@Fredrik Se si decide di archiviare i dati in un file, perché come dati di base64? Possiamo semplicemente salvare il file di immagine originale. – Googlebot

+0

Ho pensato che lo stavi spedendo da dispositivo come iPhone o qualcos'altro. Quindi non si desidera inviare dati grezzi ma la stringa base64 in JSON o qualcosa del genere. – Fredrik

risposta

42

Pro base64: la rappresentazione codificata gestita è una stringa abbastanza sicura. Non contiene caratteri di controllo né citazioni. Quest'ultimo punto aiuta nei tentativi di iniezione SQL. Non mi aspetto alcun problema di aggiungere semplicemente il valore a una stringa di query SQL "codificata a mano".

Pro BLOB: il software di gestione database sa che tipo di dati deve aspettarsi. Può ottimizzare per quello. Se si memorizzasse base64 in un campo TESTO, potrebbe tentare di creare un indice o un'altra struttura dati per esso, che sarebbe davvero bello e utile per dati di testo "reali" ma inutili e uno spreco di tempo e spazio per i dati di immagine. Ed è il più piccolo, come numero di byte, rappresentazione.

+0

very useful comparison. My worry is mainly about security. I am not sure if saving binary can open any security hole for SQL injection. – Googlebot

+0

That should depend on "proper" and "safe" handling of the data to the database. As I'm not familiar with PHP, what you seem to use, I can't give you tips on that. In java the tools I use (Hibernate/JPA) take care of that for me. :) – user1252434

+3

Escaping the input protects against SQL injection attacks, not the storage mechanism. I admit that I've never needed to enter an image by hand into a query. –

39

Io sostengo che le immagini (file) NON sono solitamente memorizzate in un database base64 codificato. Invece, sono memorizzati nella loro forma binaria grezza in una colonna (o un file) binario (blob).

Base64 viene utilizzato solo come meccanismo di trasporto, non per la conservazione. Ad esempio, è possibile incorporare un'immagine codificata Base64 in un documento XML o un messaggio di posta elettronica.

Base64 è anche compatibile con lo stream. Puoi codificare e decodificare al volo (senza conoscere la dimensione totale dei dati).

Mentre base64 va bene per il trasporto, non memorizzare le immagini codificate in base64.

Base64 non fornisce alcun valore di checksum o qualsiasi valore per l'archiviazione.

La codifica Base64 aumenta il requisito di archiviazione del 33% su un formato binario non elaborato. Aumenta anche la quantità di dati che devono essere letti dalla memoria persistente, che è ancora generalmente il collo di bottiglia più grande in informatica. In genere è più veloce leggere meno byte e codificarli al volo. Solo se il tuo sistema è vincolato alla CPU invece che a IO, e stai regolarmente trasmettendo l'immagine in base64, allora considera l'archiviazione in base64.

Le immagini in linea (immagini codificate in base64 incorporate nell'HTML) sono un collo di bottiglia in sé: invii il 33% di dati in più sul filo e lo fai in serie (il browser Web deve attendere le immagini in linea prima che possa terminare il download della pagina HTML).

Se si desidera conservare le immagini codificate in base64, per favore, qualunque cosa si faccia, assicurarsi di non memorizzare i dati codificati Base64 in una colonna UTF8 quindi indicizzarla.

+2

buon chiarimento; ma se cerchi, troverai molti tutorial per la memorizzazione come base64 e alcuni per l'archiviazione binaria. – Googlebot

+1

Base64 non fornisce alcun checksum o nulla di qualsiasi valore per l'archiviazione. Se fornisci un collegamento con un argomento per il suo utilizzo come spazio di archiviazione, te lo ridurrò per te. :) –

+2

@MarcusAdams Che ne dici di archiviare le immagini degli avatar degli utenti usando base64? Perché dovrei voler tradurre indietro e inoltrare tramite base64/raw quando posso solo codificare una volta e dimenticarlo? –

0

Raccomando di consultare database moderni come NoSQL e inoltre sono d'accordo con il post user1252434. Ad esempio, sto memorizzando alcuni PNG da 500kb < come base64 sul mio Mongo db con il set binario impostato su true senza alcun impatto sulle prestazioni. Mongo può essere utilizzato per archiviare file di grandi dimensioni come i video da 10 MB e che possono offrire enormi vantaggi in termini di risparmio di tempo nelle ricerche di metadati per tali video, vedere storing large objects and files in mongodb.

+0

Da quello che sto vedendo nella specifica di bson, MongoDb memorizza quindi gli array di byte non codificati in base64, ma come byte grezzi, prefissati con la loro lunghezza. – Volker