Domanda

Quindi sto utilizzando un'app che memorizza pesantemente le immagini nel DB.Qual è la tua prospettiva a riguardo?Sono più un tipo che memorizza la posizione nel filesystem, piuttosto che memorizzarla direttamente nel DB.

Quali pensi siano i pro/contro?

Nessuna soluzione corretta

Altri suggerimenti

Sono responsabile di alcune applicazioni che gestiscono molti TB di immagini.Abbiamo trovato quel deposito percorsi dei file nel database per essere migliore.

Ci sono un paio di problemi:

  • l'archiviazione del database è generalmente più costosa dell'archiviazione del file system
  • puoi superaccelerare l'accesso al file system con prodotti standard disponibili in commercio
    • ad esempio, molti server Web utilizzano il sistema operativo inviare file() chiamata di sistema per inviare in modo asincrono un file direttamente dal file system all'interfaccia di rete.Le immagini archiviate in un database non beneficiano di questa ottimizzazione.
  • cose come server web, ecc., non necessitano di codifica o elaborazione speciale per accedere alle immagini nel file system
  • i database vincono laddove l’integrità transazionale tra l’immagine e i metadati è importante.
    • è più complesso gestire l'integrità tra i metadati del db e i dati del file system
    • è difficile (nel contesto di un'applicazione web) garantire che i dati siano stati scaricati sul disco del filesystem

Come con la maggior parte dei problemi, non è così semplice come sembra.Ci sono casi in cui avrebbe senso archiviare le immagini nel database.

  • Stai archiviando immagini che stanno cambiando dinamicamente, diciamo fatture e volevi ottenere una fattura com'era il 1 ° gennaio 2007?
  • Il governo vuole che tu mantenga 6 anni di storia
  • Le immagini archiviate nel database non richiedono una strategia di backup diversa.Le immagini archiviate nel filesystem lo fanno
  • È più semplice controllare l'accesso alle immagini se si trovano in un database.Gli amministratori inattivi possono accedere a qualsiasi cartella sul disco.Ci vuole un amministratore davvero determinato per curiosare in un database per estrarre le immagini

D'altra parte ci sono problemi associati

  • Richiedi un codice aggiuntivo per estrarre e trasmettere in streaming le immagini
  • La latenza può essere più lenta dell'accesso diretto al file
  • Carico più pesante sul server del database

Archivio di file.Gli ingegneri di Facebook ne hanno parlato molto.Un vantaggio era conoscere il limite pratico dei file in una directory.

Ago in un pagliaio:Archiviazione efficiente di miliardi di foto

Potrebbe trattarsi di un'ipotesi un po' remota, ma se stai utilizzando (o intendi utilizzare) SQL Server 2008 ti consiglio di dare un'occhiata al nuovo FileStream tipo di dati.

FileStream risolve la maggior parte dei problemi relativi alla memorizzazione dei file nel DB:

  1. I BLOB vengono effettivamente archiviati come file in una cartella.
  2. È possibile accedere ai BLOB utilizzando O una connessione al database O sul filesystem.
  3. I backup sono integrati.
  4. La migrazione "funziona e basta".

Tuttavia, la "Crittografia trasparente dei dati" di SQL non crittografa gli oggetti FileStream, quindi se questa è una considerazione, potrebbe essere meglio memorizzarli semplicemente come varbinary.

Dall'articolo MSDN:

Le istruzioni Transact-SQL possono inserire, aggiornare, eseguire query, eseguire ricerche ed eseguire il backup dei dati FILESTREAM.Le interfacce del file system Win32 forniscono l'accesso in streaming ai dati.
FILESTREAM utilizza la cache del sistema NT per memorizzare nella cache i dati dei file.Ciò consente di ridurre eventuali effetti che i dati FILESTREAM potrebbero avere sulle prestazioni del Motore di database.Il pool di buffer di SQL Server non viene utilizzato;pertanto, questa memoria è disponibile per l'elaborazione delle query.

I percorsi dei file nel DB sono decisamente la strada da percorrere: ho sentito storie su storie di clienti con TB di immagini che è diventato un incubo cercare di archiviare una quantità significativa di immagini in un DB: il solo calo delle prestazioni è eccessivo.

Nella mia esperienza, a volte la soluzione più semplice è denominare le immagini in base alla chiave primaria.Quindi è facile trovare l'immagine che appartiene ad un particolare record e viceversa.Ma allo stesso tempo non stai immagazzinando nulla sull'immagine nel database.

Il trucco qui è non diventare un fanatico.

Una cosa da notare qui è che nessuno nel campo dei file system professionali ha elencato un particolare file system.Ciò significa che tutto, da FAT16 a ZFS, batte facilmente ogni database?

NO.

La verità è che molti database battono molti file system, anche quando parliamo solo di pura velocità.

La linea d'azione corretta è prendere la decisione giusta per il tuo scenario preciso e, per farlo, avrai bisogno di alcuni numeri e di alcune stime dei casi d'uso.

Nei luoghi in cui è NECESSARIO garantire l'integrità referenziale e la conformità ACID, è richiesta la memorizzazione delle immagini nel database.

Non è possibile garantire a livello transazionale che l'immagine e i metadati relativi all'immagine archiviati nel database facciano riferimento allo stesso file.In altre parole, è impossibile garantire che il file sul filesystem venga modificato solo nello stesso momento e nella stessa transazione dei metadati.

Come altri hanno già detto, SQL 2008 viene fornito con un tipo Filestream che ti consente di memorizzare un nome file o un identificatore come puntatore nel database e memorizza automaticamente l'immagine sul tuo file system, il che è un ottimo scenario.

Se utilizzi un database più vecchio, direi che se lo memorizzi come dati blob, non otterrai davvero nulla dal database in termini di funzionalità di ricerca, quindi probabilmente è meglio per memorizzare un indirizzo su un filesystem e memorizzare l'immagine in questo modo.

In questo modo risparmierai anche spazio sul tuo filesystem, poiché salverai solo la quantità esatta di spazio, o anche lo spazio compattato sul filesystem.

Inoltre, potresti decidere di salvare con alcune strutture o elementi che ti consentano di sfogliare le immagini grezze nel tuo file system senza alcun riscontro db o di trasferire i file in blocco su un altro sistema, disco rigido, S3 o un altro scenario, aggiornando la posizione in il tuo programma, ma mantieni la struttura, ancora una volta senza troppi problemi cercando di portare le immagini fuori dal tuo db quando cerchi di aumentare lo spazio di archiviazione.

Probabilmente, ti consentirebbe anche di inserire alcuni elementi di memorizzazione nella cache, basati sugli URL di immagini comunemente colpiti nel tuo motore/programma web, in modo da salvare te stesso anche lì.

Piccole immagini statiche (non più di un paio di mega) che non vengono modificate frequentemente, dovrebbero essere archiviate nel database.Questo metodo presenta numerosi vantaggi, tra cui una più semplice portabilità (le immagini vengono trasferite con il database), un backup/ripristino più semplice (le immagini vengono sottoposte a backup con il database) e una migliore scalabilità (una cartella del file system con migliaia di piccoli file di miniature sembra un incubo di scalabilità per Me).

Servire immagini da un database è semplice, basta implementare un gestore http che serve l'array di byte restituito dal server DB come flusso binario.

Ecco un interessante white paper sull'argomento.

In BLOB o Non BLOB:Archiviazione di oggetti di grandi dimensioni in un database o in un file system

La risposta è, dipende." Certamente dipenderebbe dal server di database e dal suo approccio alla memoria BLOB.Dipende anche dal tipo di dati archiviati nei BLOB e dalla modalità di accesso a tali dati.

I file di dimensioni più piccole possono essere archiviati e consegnati in modo efficiente utilizzando il database come meccanismo di archiviazione.I file più grandi probabilmente verrebbero archiviati meglio utilizzando il file system, soprattutto se verranno modificati/aggiornati spesso.(la frammentazione dei BLOB diventa un problema per quanto riguarda le prestazioni.)

Ecco un ulteriore punto da tenere a mente.Uno dei motivi a sostegno dell'utilizzo di un database per archiviare i BLOB è la conformità ACID.Tuttavia, l'approccio utilizzato dai tester nel white paper (opzione Bulk Logged di SQL Server) che ha raddoppiato la velocità effettiva di SQL Server, ha effettivamente modificato la "D" in ACID in una "d", poiché i dati del BLOB non venivano registrati con l'iniziale scrive per la transazione.Pertanto, se la conformità ACID completa è un requisito importante per il sistema, dimezzare le cifre relative alla velocità effettiva di SQL Server per le scritture del database quando si confrontano l'I/O dei file con l'I/O dei BLOB del database.

Una cosa che non ho ancora visto nessuno menzionare, ma che vale sicuramente la pena notare, è che ci sono problemi associati alla memorizzazione di grandi quantità di immagini anche nella maggior parte dei filesystem.Ad esempio, se adotti l'approccio menzionato sopra e dai un nome a ciascun file immagine dopo la chiave primaria, sulla maggior parte dei file system incontrerai problemi se provi a inserire tutte le immagini in un'unica grande directory una volta raggiunto un numero molto elevato di immagini ( per esempio.nell'ordine di centinaia di migliaia o milioni).

Una volta che la soluzione comune a questo problema è inserirli in un albero bilanciato di sottodirectory.

Qualcosa che nessuno ha menzionato è che il DB garantisce azioni atomiche, integrità transazionale e gestione della concorrenza.Anche l'integrità referenziale è fuori dalla finestra con un filesystem, quindi come fai a sapere che i nomi dei tuoi file sono ancora corretti?

Se hai le tue immagini in un file system e qualcuno sta leggendo il file mentre stai scrivendo una nuova versione o addirittura eliminando il file, cosa succede?

Utilizziamo i BLOB perché sono anche più facili da gestire (backup, replica, trasferimento).Funzionano bene per noi.

Il problema con la memorizzazione solo dei percorsi dei file delle immagini in un database è che l'integrità del database non può più essere forzata.

Se l'immagine effettiva a cui punta il percorso file non è più disponibile, il database presenta involontariamente un errore di integrità.

Dato che le immagini sono i dati effettivi ricercati e che possono essere gestite più facilmente (le immagini non scompariranno all'improvviso) in un database integrato piuttosto che dover interfacciarsi con qualche tipo di filesystem (se si accede al filesystem in modo indipendente, le immagini POTREBBERO "scomparire" improvvisamente), preferirei memorizzarle direttamente come BLOB o simili.

Nell'azienda in cui lavoravo archiviavamo 155 milioni di immagini in un database Oracle 8i (poi 9i).Vale 7,5 TB.

Normalmente, sono fermamente contrario a prendere la parte più costosa e più difficile da scalare della tua infrastruttura (il database) e caricarla di tutto il carico.D'altra parte:Semplifica notevolmente la strategia di backup, soprattutto quando si dispone di più server Web ed è necessario mantenere in qualche modo sincronizzati i dati.

Come la maggior parte delle altre cose, dipende dalle dimensioni e dal budget previsti.

Abbiamo implementato un sistema di imaging dei documenti che memorizza tutte le sue immagini nei campi BLOB SQL2005.Al momento ci sono diverse centinaia di GB e stiamo riscontrando tempi di risposta eccellenti e un degrado delle prestazioni minimo o nullo.Inoltre, per la conformità normativa, disponiamo di un livello middleware che archivia i documenti appena pubblicati su un sistema jukebox ottico che li espone come un file system NTFS standard.

Siamo rimasti molto soddisfatti dei risultati, in particolare per quanto riguarda:

  1. Facilità di replica e backup
  2. Capacità di implementare facilmente un sistema di versione dei documenti

Se si tratta di un'applicazione basata sul Web, potrebbero esserci vantaggi nell'archiviare le immagini su una rete di distribuzione di archiviazione di terze parti, come S3 di Amazon o la piattaforma Nirvanix.

Assunzione:L'applicazione è abilitata al Web/basata sul Web

Mi sorprende che nessuno ne abbia veramente parlato...delegarlo ad altri specialisti -> utilizzare un provider di hosting di immagini/file di terze parti.

Archivia i tuoi file su un servizio online a pagamento come

Un altro thread di StackOverflow ne parla Qui.

Questo filo spiega perché dovresti utilizzare un provider di hosting di terze parti.

Ne vale davvero la pena.Lo immagazzinano in modo efficiente.Nessuna larghezza di banda caricata dai tuoi server alle richieste dei client, ecc.

Se non utilizzi SQL Server 2008 e hai validi motivi per inserire file di immagine specifici nel database, potresti adottare l'approccio "entrambi" e utilizzare il file system come cache temporanea e utilizzare il database come repository principale .

Ad esempio, la logica aziendale può verificare se esiste un file immagine sul disco prima di pubblicarlo, recuperandolo dal database quando necessario.Ciò ti offre la capacità di più server Web e meno problemi di sincronizzazione.

Non sono sicuro di quanto questo sia un esempio del "mondo reale", ma attualmente ho un'applicazione disponibile che memorizza i dettagli per un gioco di carte collezionabili, comprese le immagini delle carte.Premesso che il conteggio dei record per il database è di soli 2851 record fino ad oggi, ma dato il fatto che alcune carte sono state rilasciate più volte e hanno illustrazioni alternative, in realtà era più efficiente in termini di dimensioni scansionare il "quadrato primario" dell'illustrazione e poi dinamicamente generare il bordo e gli effetti vari per la carta quando richiesto.

Il creatore originale di questa libreria di immagini ha creato una classe di accesso ai dati che esegue il rendering dell'immagine in base alla richiesta e lo fa abbastanza velocemente per la visualizzazione e la singola scheda.

Ciò facilita anche la distribuzione/gli aggiornamenti quando vengono rilasciate nuove carte, invece di comprimere un'intera cartella di immagini e inviarle nel tubo e garantire che venga creata la struttura di cartelle corretta, aggiorno semplicemente il database e chiedo all'utente di scaricarlo di nuovo.Attualmente ha una dimensione massima di 56 MB, il che non è eccezionale, ma sto lavorando su una funzionalità di aggiornamento incrementale per le versioni future.Inoltre, esiste una versione "senza immagini" dell'applicazione che consente a chi accede tramite accesso remoto di ottenere l'applicazione senza ritardi nel download.

Questa soluzione ha funzionato benissimo fino ad oggi poiché l'applicazione stessa è concepita come una singola istanza sul desktop.Esiste un sito Web in cui tutti questi dati vengono archiviati per l'accesso online, ma non utilizzerei in alcun modo la stessa soluzione per questo.Sono d'accordo che l'accesso ai file sarebbe preferibile perché si adatterebbe meglio alla frequenza e al volume delle richieste effettuate per le immagini.

Spero che non siano troppe chiacchiere, ma ho visto l'argomento e volevo fornire alcune mie intuizioni da un'applicazione su piccola/media scala di relativamente successo.

SQL Server 2008 offre una soluzione che offre il meglio di entrambi i mondi: Il tipo di dati filestream.

Gestiscilo come una normale tabella e sfrutta le prestazioni del file system.

Dipende dal numero di immagini che memorizzerai e anche dalle loro dimensioni.In passato ho utilizzato database per archiviare immagini e la mia esperienza è stata abbastanza buona.

IMO, i vantaggi dell'utilizzo del database per archiviare le immagini sono:

UN.Non hai bisogno della struttura FS per contenere le tue immagini
B.Gli indici dei database funzionano meglio degli alberi FS quando è necessario archiviare un numero maggiore di elementi
C.Il database ottimizzato esegue un buon lavoro memorizzando nella cache i risultati della query
D.I backup sono semplici.Funziona bene anche se è impostata la replica e il contenuto viene distribuito da un server vicino all'utente.In questi casi non è necessaria la sincronizzazione esplicita.

Se le tue immagini saranno piccole (diciamo < 64k) e il motore di archiviazione del tuo db supporta BLOB in linea (nei record), migliora ulteriormente le prestazioni poiché non è richiesto alcun riferimento indiretto (viene raggiunta la località di riferimento).

Memorizzare le immagini può essere una cattiva idea quando si ha a che fare con un numero limitato di immagini di grandi dimensioni.Un altro problema con la memorizzazione delle immagini in db è che, i metadati come la creazione, le date di modifica devono essere gestite dall'applicazione.

Recentemente ho creato un'app PHP/MySQL che memorizza file PDF/Word in una tabella MySQL (finora fino a 40 MB per file).

Professionisti:

  • I file caricati vengono replicati sul server di backup insieme a tutto il resto, non è necessaria alcuna strategia di backup separata (tranquillità).
  • Configurare il server web è leggermente più semplice perché non ho bisogno di avere una cartella di upload/e dire a tutte le mie applicazioni dove si trova.
  • Posso utilizzare le transazioni per le modifiche per migliorare l'integrità dei dati: non devo preoccuparmi di file orfani e mancanti

Contro:

  • mysqldump ora impiega moooolto tempo perché ci sono 500 MB di dati di file in una delle tabelle.
  • Nel complesso non è molto efficiente in termini di memoria/CPU rispetto al filesystem

Definirei la mia implementazione un successo, si prende cura dei requisiti di backup e semplifica il layout del progetto.Le prestazioni vanno bene per le 20-30 persone che utilizzano l'app.

Nella mia esperienza ho dovuto gestire entrambe le situazioni:immagini archiviate nel database e immagini nel file system con percorso archiviato nel db.

La prima soluzione, immagini nel database, è un po' più "pulita" in quanto il livello di accesso ai dati dovrà occuparsi solo degli oggetti del database;ma questo va bene solo quando si ha a che fare con numeri bassi.

Ovviamente le prestazioni di accesso al database quando si ha a che fare con oggetti binari di grandi dimensioni stanno peggiorando e le dimensioni del database aumenteranno molto, causando nuovamente una perdita di prestazioni...e normalmente lo spazio del database è molto più costoso dello spazio del file system.

D'altra parte, avere oggetti binari di grandi dimensioni archiviati nel file system richiederà piani di backup che devono considerare sia il database che il file system e questo può rappresentare un problema per alcuni sistemi.

Un altro motivo per scegliere il file system è quando devi condividere i dati delle tue immagini (o suoni, video, qualunque cosa) con accesso di terze parti:in questi giorni sto sviluppando un'app web che utilizza immagini a cui è necessario accedere "dall'esterno" della mia web farm in modo tale che l'accesso al database per recuperare dati binari sia semplicemente impossibile.Quindi a volte ci sono anche considerazioni progettuali che ti porteranno a una scelta.

Considera anche, quando fai questa scelta, se devi gestire i permessi e l'autenticazione quando accedi agli oggetti binari:questi requisiti normalmente possono essere risolti in modo più semplice quando i dati vengono archiviati in db.

Una volta ho lavorato su un'applicazione di elaborazione delle immagini.Abbiamo archiviato le immagini caricate in una directory simile a /images/[data odierna]/[numero ID].Ma abbiamo anche estratto i metadati (dati exif) dalle immagini e li abbiamo archiviati nel database, insieme a un timestamp e simili.

In un progetto precedente ho archiviato le immagini sul file system e ciò ha causato molti mal di testa con backup, replica e la sincronizzazione del file system con il database.

Nel mio ultimo progetto sto memorizzando le immagini nel database e le memorizzo nella cache del filesystem, e funziona davvero bene.Finora non ho avuto problemi.

Seconda la raccomandazione sui percorsi dei file.Ho lavorato su un paio di progetti che dovevano gestire raccolte di risorse di grandi dimensioni e qualsiasi tentativo di archiviare le cose direttamente nel DB ha provocato dolore e frustrazione a lungo termine.

L'unico vero "pro" che mi viene in mente riguardo alla loro memorizzazione nel DB è la possibilità di semplificare le singole risorse di immagine.Se non ci sono percorsi di file da utilizzare e tutte le immagini vengono trasmesse direttamente dal DB, non c'è pericolo che un utente trovi file a cui non dovrebbe avere accesso.

Sembra che sarebbe meglio risolverlo con uno script intermedio che estrae i dati da un archivio di file inaccessibile dal web.Quindi l'archiviazione DB non è REALMENTE necessaria.

Si dice in giro che, a meno che tu non sia un fornitore di database che cerca di dimostrare che il tuo database può farlo (come, diciamo, Microsoft che si vanta di Terraserver che memorizza un milione di immagini in SQL Server), non è una buona idea.Quando l'alternativa, ovvero l'archiviazione di immagini su file server e percorsi nel database, è molto più semplice, perché preoccuparsi?I campi blob sono un po' come le capacità fuoristrada dei SUV: la maggior parte delle persone non li usa, quelli che lo fanno di solito si mettono nei guai, e poi c'è chi lo fa, ma solo per il gusto di farlo.

Memorizzare un'immagine nel database significa comunque che i dati dell'immagine finiscono da qualche parte nel file system ma sono oscurati in modo da non potervi accedere direttamente.

+ves:

  • integrità del database
  • è facile da gestire poiché non devi preoccuparti di mantenere sincronizzato il filesystem quando un'immagine viene aggiunta o eliminata

-ves:

  • penalizzazione delle prestazioni: una ricerca nel database è solitamente più lenta di una ricerca nel filesystem
  • non è possibile modificare direttamente l'immagine (ritagliare, ridimensionare)

Entrambi i metodi sono comuni e praticati.Dai un'occhiata ai vantaggi e agli svantaggi.In ogni caso, dovrai pensare a come superare gli svantaggi.L'archiviazione nel database di solito significa modificare i parametri del database e implementare una sorta di memorizzazione nella cache.L'uso del filesystem richiede di trovare un modo per mantenere sincronizzati filesystem+database.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top