2009-11-11 17 views
10

Non riesco a decidere se dovrei utilizzare il tipo di campo blob MySQL in un progetto imminente che ho.Devo usare il tipo di blob MySQL?

I miei requisiti di base sono, ci saranno alcuni record del database che possono essere visualizzati e avere più file caricati e "allegati" a quei record. Vedere le registrazioni può essere limitato a determinate persone caso per caso. Qualsiasi tipo di file può essere caricato praticamente senza restrizioni.

Quindi, guardandolo in un modo, se vado sul percorso MySQL, non devo preoccuparmi che il virus si insinui o che i file php casuali vengano caricati e in qualche modo eseguiti. Ho anche un percorso molto più semplice per l'autorizzazione e il mantenimento dei dati legati a un record.

L'altro percorso evidente è la memorizzazione dei dati in una struttura di cartelle specifica al di fuori della radice del web. in questo caso dovrei elaborare una speciale convenzione di denominazione per cartelle/file per tenere traccia di ciò che fanno riferimento all'interno del database.

C'è un colpo di prestazioni con l'utilizzo del tipo di campo blob MySQL? Sono preoccupato per la scelta di una soluzione che ostacolerà la crescita futura del sito web, nonché la scelta di una soluzione che non sarà facile da mantenere.

risposta

10

Se il server Web servirà questi file caricati sul Web, le prestazioni saranno quasi sicuramente migliori se vengono archiviate nel filesystem. Il server Web sarà quindi in grado di applicare hint di caching HTTP come Last-Modified e ETag, il che aiuterà le prestazioni per gli utenti che accedono allo stesso file più volte. Inoltre, il server Web imposterà automaticamente il Content-Type corretto per il file durante la pubblicazione. Se memorizzi i BLOB nel database, finirai per implementare le funzionalità sopra menzionate e altro ancora quando dovresti ottenerle gratuitamente dal tuo server web.

Inoltre, estrarre dal database dati di blob di grandi dimensioni può rappresentare un collo di bottiglia per le prestazioni sul database. Inoltre, i backup del database saranno probabilmente più lenti perché eseguiranno il backup di più dati. Se si stanno eseguendo query ad-hoc durante lo sviluppo, sarà scomodo vedere blob di grandi dimensioni nei set di risultati per le istruzioni select. Se vuoi semplicemente ispezionare un file caricato, sarà scomodo e rotatorio farlo perché sarà memorizzato in modo impacciato in una colonna del database.

Vorrei attenermi alla pratica comune di archiviare i file sul filesystem e il percorso del file nel database.

2

Grandi volumi di dati finiranno col pagare le prestazioni. MS SQL 2008 ha un modo speciale di memorizzare i dati binari nel file system:

http://msdn.microsoft.com/en-us/library/cc949109.aspx

userei l'approccio simile anche per il progetto anche.

È possibile creare una tabella FILE che manterrà informazioni sui file come i nomi originali, ad esempio. Per archiviare in modo sicuro i file sul disco, rinominarli utilizzando, ad esempio, GUID. Archiviare nuovi nomi di file nella tabella FILES e quando l'utente deve scaricarlo, è possibile individuarlo facilmente sul disco e trasferirlo in streaming all'utente.

0

Secondo me la memorizzazione di file nel database è una cattiva idea. Ciò che puoi memorizzare è id, nome, tipo, eventualmente hash MD5 di file e data inserita. I file possono essere caricati nella cartella al di fuori del luogo pubblico. Inoltre, dovresti essere preoccupato che non è consigliabile conservare più di 1000 file in una cartella. Quindi, cosa devi creare una nuova cartella ogni volta che l'ID del file viene aumentato di 1000.

9

C'è un calo di prestazioni con l'utilizzo del tipo di campo blob MySQL?

Non intrinsecamente, ma se si dispone di BLOB di grandi dimensioni che intasano le tabelle e la memoria cache che provocherà sicuramente un impatto sulle prestazioni.

L'altro percorso evidente è la memorizzazione dei dati in una struttura di cartelle specifica al di fuori della radice del web. in questo caso dovrei elaborare una speciale convenzione di denominazione per cartelle/file per tenere traccia di ciò che fanno riferimento all'interno del database.

Sì, questo è un approccio comune. Di solito si fa qualcosa di simile a cartelle con il nome di ogni tabella a cui sono associate, contenenti nomi di file basati solo sulla chiave primaria (idealmente un numero intero, sicuramente mai nulla inviata dall'utente).

È un'idea migliore? Dipende. Esistono vantaggi semplificati per l'implementazione di disporre di un solo archivio dati e non doversi preoccupare di fornire agli utenti Web accesso in scrittura a qualsiasi cosa. Inoltre, se possono essere eseguite più copie dell'app (ad es. Bilanciamento del carico attivo-attivo), è necessario sincronizzare lo spazio di archiviazione, che è molto più semplice con un database che con un file system.

Se si utilizza il filesystem anziché un blob, la domanda è quindi, si ottiene il server Web per servirlo puntando un alias nella cartella?

  • + è super veloce
  • + cache e
  • - in più server di configurazione: directory virtuale; ha bisogno di estensione di file appropriato per tornare desiderato Content-Type
  • - configurazione del server in più: necessità di aggiungere Content-Disposition: attachment/X-Content-Type-Options intestazioni per fermare IE sniffing per HTML come parte di anti-XSS misura la

o ti servono manualmente il file avere uno script sul lato server sputarlo fuori, come si dovrebbe servire da un blob MySQL?

  • - è potenzialmente lento
  • - ha bisogno di un bel po 'di manuale di If-Modified-Since e ETag la gestione di cache correttamente
  • + possono utilizzare propri metodi di controllo di accesso dell'applicazione
  • + facile aggiungere corretta Content-Type e Content-Disposition Disposizioni dallo script di servizio

Questo è un trade-off non c'è una risposta accettata a livello globale per.

2

Molte persone raccomandano di non archiviare gli allegati (di solito questo si applica alle immagini) in blob nel database. Preferiscono invece archiviare un percorso come stringa nel database e archiviare il file in un posto sicuro sul filesystem. Ci sono alcuni meriti a questo:

  • I backup del database e del database sono più piccoli.
  • È più facile modificare i file sul filesystem se è necessario lavorare con essi ad hoc.
  • I file system sono in grado di archiviare file. I database sono bravi a memorizzare tuple. Lascia che ognuno faccia ciò che è buono.

Ci sono controargomenti anche, che supportano allegati mettendo in un blob:

  • eliminazione di una riga in un database elimina automaticamente l'allegato associato.
  • Il rollback e l'isolamento della transazione funzionano come previsto quando i dati si trovano in una riga, ma non quando una parte dei dati si trova nel file system.
  • I backup sono più semplici se tutti i dati sono nel database. Non è necessario preoccuparsi di eseguire backup coerenti di dati che cambiano contemporaneamente durante la procedura di backup.

Quindi la soluzione migliore dipende da come si stanno utilizzando i dati nell'applicazione. Non esiste una risposta valida per tutti.

So che hai taggato la tua domanda con MySQL, ma se la gente che legge questa domanda utilizza altre marche di RDBMS, potrebbe voler esaminare BFILE quando si utilizza Oracle o FILESTREAM quando si utilizza Microsoft SQL Server 2008. Questi ti danno la possibilità memorizzare i file al di fuori del database ma accedervi come se facessero parte di una riga in una tabella di database (più o meno).

2

I dati devono essere memorizzati in un'unica posizione: il database. Questo tipo di prestazioni e tipo di contenuto non è affatto un problema, poiché non vi è nulla che impedisca di memorizzare nella cache quei campi BLOB sul server Web locale e di servirlo da lì, come viene richiesto per la prima volta. Non è necessario accedere a tale tabella in ogni visualizzazione di pagina.

Questa cache del file system può essere svuotata in qualsiasi momento, il che influirà solo temporaneamente sulle prestazioni mentre viene ricaricato automaticamente. Vi permetterà anche di usare un database e molti server web man mano che la vostra applicazione cresce, avranno semplicemente tutti una cache locale sul file system.

5

Nella mia esperienza l'archiviazione di un BLOB in MySQL è OK, a condizione che si memorizzi solo il BLOB in una tabella, mentre gli altri campi si trovano in un'altra tabella (unita). Al contrario, la ricerca nei campi di una tabella con alcuni campi standard e un campo blob con 100 MB di dati può rallentare notevolmente le query.

ho dovuto cambiare lo strato di dati di una mailing app per questo problema in cui le email sono stati conservati con il contenuto nella stessa tabella come data di invio, indirizzi e-mail, ecc Si stava prendendo 9 secondi per la ricerca 10000 messaggi di posta elettronica. Ora ci vuole quello che dovrebbe prendere ;-)