¿Cuál es el mejor lugar para almacenar archivos binarios relacionados con datos en su base de datos? Deberías:
- Almacenar en la base de datos con un blob
- Almacenar en el sistema de archivos con un enlace en la base de datos
- Almacene en el sistema de archivos pero cambie el nombre a un hash de los contenidos y almacene el hash en la base de datos
- Algo que no he pensado
Las ventajas de (1) son (entre otras) que se preserva la atomicidad de las transacciones. El costo es que puede aumentar drásticamente los requisitos de almacenamiento (y la transmisión / copia de seguridad asociada)
El objetivo de (3) es preservar la atomicidad hasta cierto punto: si puede exigir que el sistema de archivos en el que está escribiendo no permita que los archivos se modifiquen o eliminen, y siempre tiene el hash correcto como nombre de archivo. La idea sería escribir el archivo en el sistema de archivos antes de permitir la inserción / actualización haciendo referencia al hash; si esta transacción falla después de la escritura del sistema de archivos pero antes del DML de la base de datos, está bien porque el sistema de archivos está 'fingiendo' siendo el repositorio de todos posibles archivos y hashes: no importa si hay algunos archivos allí a los que no se apunta (y puede limpiarlos periódicamente si tiene cuidado)
EDITAR:
Parece que algunos RDBMS tienen esto cubierto de manera individual, me interesaría saber cómo lo hacen otros, y particularmente en una solución para postgres
fuente
Respuestas:
Almacenar en la base de datos con un blob
Una desventaja es que hace que los archivos de su base de datos sean bastante grandes y posiblemente demasiado grandes para hacer una copia de seguridad de su configuración existente. Una ventaja es la integridad y la atomicidad.
Almacenar en el sistema de archivos con un enlace en la base de datos
Me he encontrado con desastres tan horribles haciendo esto, y me asusta que la gente siga sugiriéndolo. Algunos de los desastres incluyen:
C:\
camino hasta el.doc
y no todas las versiones de NT pudieron manejar rutas largas.Almacene en el sistema de archivos pero cambie el nombre a un hash de los contenidos y almacene el hash en la base de datos
El último lugar en el que trabajé hizo esto basado en mi explicación de los escenarios anteriores. Pensaban que era un compromiso entre la incapacidad de la organización para obtener experiencia con grandes bases de datos (cualquier cosa mayor que aproximadamente 40G fue ordenada para ser "demasiado grande"), la incapacidad corporativa para comprar discos duros grandes y la imposibilidad de comprar un respaldo más moderno solución, y la necesidad de escapar de los riesgos # 1 y # 3 que identifiqué anteriormente.
Mi opinión es que almacenar en la base de datos como un blob es una mejor solución y más escalable en un escenario de varios servidores, especialmente con problemas de disponibilidad y de conmutación por error.
fuente
Número 1 para la integridad completa de los datos. Use las otras opciones si no le importa la calidad de los datos. Es así de simple.
La mayoría de los RDBMS tienen optimizaciones para almacenar BLOB (p. Ej., Flujo de archivos de SQL Server)
fuente
Si va por Oracle, eche un vistazo a dbfs y Secure Files.
Secure Files lo dice todo, mantenga TODOS sus datos seguros en la base de datos. Está organizado en globos. Secure Files es una versión modernizada de los lobs, que debe activarse.
dbfs es un sistema de archivos en la base de datos. Puede montarlo de manera similar a un sistema de archivos de red, en un host Linux. Es realmente poderoso. Ver blog También tiene muchas opciones para ajustarse a sus necesidades específicas. Al ser un dba, dado un sistema de archivos (basado en la base de datos, montado en Linux), creé una base de datos Oracle sin problemas. (una base de datos, almacenada en una ... base de datos). No es que esto sea muy útil, pero muestra el poder.
Más ventajas son: disponibilidad, respaldo, recuperación, todas las lecturas consistentes con los otros datos relacionales.
A veces, el tamaño se da como una razón para no almacenar documentos en la base de datos. Es probable que se deba hacer una copia de seguridad de esos datos, por lo que no es una buena razón para no almacenarlos en la base de datos. Especialmente en una situación en la que los documentos antiguos deben considerarse de solo lectura, es fácil hacer que grandes partes de la base de datos sean de solo lectura. En ese caso, esas partes de la base de datos ya no necesitan una copia de seguridad de alta frecuencia.
Una referencia en una tabla a algo fuera de la base de datos no es segura. Se puede manipular, es difícil de verificar y se puede perder fácilmente. ¿Qué hay de las transacciones? La base de datos ofrece soluciones para todos estos problemas. Con Oracle DBFS, puede entregar sus documentos a aplicaciones que no sean de base de datos y ni siquiera sabrían que están hurgando en una base de datos.
Una última gran sorpresa, el rendimiento de un sistema de archivos dbfs suele ser mejor que un sistema de archivos normal. Esto es especialmente cierto si los archivos son más grandes que unos pocos bloques.
fuente
Creo que la respuesta correcta aquí depende mucho de su solicitud y de la importancia de esos documentos.
Para un sistema de gestión de documentos, o un sistema en el que la capacidad de recuperación de los documentos almacenados es crítica (por lo que la mayoría de los asuntos financieros, relacionados con RR.
Sin embargo, hay muchas aplicaciones en las que creo que la decisión opuesta es apropiada.
Los sistemas de soporte técnico y los sistemas de tipo wiki son aquellos en los que creo que tiene mucho sentido mantener los datos fuera de la base de datos. Creo que algunos, como Jira, ofrecen una opción para elegir si desea almacenar documentos en línea o no.
Para una empresa mediana, almacenar documentos para un sistema de tickets en línea puede significar la diferencia entre una copia de seguridad comprimida medida en megabytes y una medida en gigabytes.
Personalmente, preferiría volver a poner en línea un sistema de venta de entradas en unos minutos y luchar con los documentos (generalmente menos importantes) durante unas horas, que aumentar mi RTO "está roto y el CTO está respirando por mi cuello" al tener que restaurar y reproducir registros de una copia de seguridad mucho más grande.
Hay otros beneficios de mantener los documentos separados.
Creo que una combinación híbrida de # 2 y # 3 podría ser inteligente. Mantenga los nombres de archivo originales, pero calcule y almacene un hash / suma de verificación del documento, de modo que tenga algún punto de referencia que ayude a la recuperación en caso de que alguien mueva o cambie el nombre del archivo.
Almacenar los archivos con sus nombres de archivo originales significa que las aplicaciones pueden literalmente tirarlos directamente de un sistema de archivos y enviarlos por cable, o en un mundo de cliente pesado, incluso puede apuntar al usuario directamente al servidor de archivos.
fuente
No lo hagas
Realmente no hay una ventaja de tener archivos almacenados en la base de datos.
¿No te parece extraño y sospechoso pensar en ti mismo?
Aún mejor, dilo en voz alta.
A los hechos:
Usando la base de datos
" PROS " ... pero no del todo :
Realmente no quiero ser parcial, pero no creo que haya más para agregar. Los profesionales no son realmente geniales si lo piensas.
Si olvidé algo comentar a continuación, mientras tanto, sigue leyendo a continuación.
CONTRAS:
Usando el sistema de archivos
PROS:
CONTRAS :
*Letra pequeña
En este momento te estás preguntando a ti mismo, espera, ¿significa que no hay contras? ¿Cómo?
El mayor error aquí es que la gente está tratando de atornillar un tornillo con un martillo.
La razón principal y me atrevería a decir que la única razón por la que esto se pregunta es por los enlaces a archivos .
Este es un problema que la base de datos no debe resolver. Incluso suena tonto si lo piensas.
Cuando en realidad, lógicamente, la aplicación debería estar a cargo de manejar y servir enlaces.
Una solución:
Esto también abstraería las rutas nativas, haría la aplicación más portátil, mantenible y permitiría cambiar a cualquier tipo de sistema de archivos sin romper nada.
En cuanto a cómo implementarlo, está más allá del alcance de esta respuesta, pero puede echar un vistazo a un ejemplo general en posiblemente el lenguaje web más utilizado (PHP):
https://github.com/symfony/Routing
https://github.com/kriswallsmith/assetic
Ambos juntos son realmente poderosos.
fuente
Quiero agregar mi experiencia aquí en cuanto a las compensaciones. En PostgreSQL, al menos, los impactos en el rendimiento son bastante mínimos en términos del servidor db. Los blobs grandes se almacenan en archivos separados, no en las tablas principales de almacenamiento dinámico a fin de apartarlos de las operaciones que pueden contar grandes cantidades de registros. Otros dbs pueden hacer algo similar.
La principal ventaja es la capacidad de mantener todos los datos relacionados en un solo lugar con fines de respaldo y atomicidad. Esto reduce en gran medida la posibilidad de que algo salga mal.
La principal desventaja no es la que he visto anteriormente, y ese es el uso de memoria en el front-end. No sé exactamente cómo cada db maneja esto, por lo que esto puede depender de la implementación, pero para PostgreSQL, los datos ingresan como una cadena ASCII con escape (posiblemente hexadecimal, posiblemente con escapes en línea). Esto luego debe convertirse de nuevo a binario en el extremo frontal. Muchos marcos que he visto para hacer esto implican pasar el valor (no como referencia) y luego construir una nueva cadena binaria basada en él. Calculé que usar Perl para hacer esto terminó usando muchas veces la memoria del binario original para lograrlo.
Veredicto: si solo se accede a los archivos ocasionalmente, los almacenaría en la base de datos. Si se accede a ellas de forma frecuente y repetida, al menos con PostgreSQL, creo que los costos superan los beneficios.
fuente
En el pasado, Microsoft promocionó la capacidad de almacenar imágenes (y tipos de datos de blobs similares) en la base de datos. Era una característica nueva y genial de SQL Server 2000 (estoy bastante seguro de que era 2000, no 7.0) y muchas personas se subieron al carro.
Almacenar BLOBS en la base de datos tiene ventajas y desventajas:
Por un lado, todos sus datos e imágenes o documentos relacionados se pueden almacenar y acceder en un solo lugar. El usuario de la aplicación no requiere permisos especiales de red, ya que es SQL el que sirve las imágenes / archivos / documentos.
Por otro lado, su base de datos puede crecer bastante, dependiendo del tamaño y la cantidad de BLOBS que esté almacenando. Esto afecta las copias de seguridad, los requisitos de almacenamiento, las operaciones de recuperación urgentes, etc.
SQL Server 2008 introdujo la transmisión de archivos. La base de datos contiene punteros a los archivos, los archivos residen en el servidor, no en la base de datos, pero cuando realiza una copia de seguridad de la base de datos, los archivos también se respaldan.
Sus copias de seguridad pueden ser bastante grandes, pero no termina con archivos / documentos / blobs / imágenes huérfanos.
Mi preferencia personal ha sido dejar que la base de datos almacene punteros / ubicaciones de red, y dejar que un servidor de archivos maneje los archivos. Los servidores de archivos están mejor optimizados para tales tareas de todos modos.
fuente
SELECT image FROM table
utiliza SSMS y se valida la imagen correcta?No almacene archivos en una base de datos.
Todos, sin excepción, que pueden ejecutar cualquier RDBMS en el mercado ya tienen una base de datos específicamente para almacenar archivos, ¡y el propio RDBMS la está usando! Esa base de datos es el sistema de archivos . Ahora hablemos sobre algunos de los posibles inconvenientes de almacenar archivos en la base de datos, así como algunos factores mitigantes específicos para almacenar archivos en la base de datos.
No hay filehandes a archivos en la base de datos. ¿Qué significa esto?
Charla del programador: NO PUEDE buscar (
fseek
), no existe la capacidad de administrar el recurso con acceso asíncrono (asyncio
oepoll
), no existesendfile
(ahorrándole la copia del espacio del núcleo).Aplicación práctica: ¿Desea enviar un video o una imagen a un cliente a través de HTTP2 / 3? Si está en la base de datos, primero tendrá que consultarlo. Para cualquier consulta que devuelva ese archivo, tendrá que esperar a que finalice la consulta completa antes de que ese archivo pueda pasar al siguiente paso. En una instalación de producción con un rdbms en un servidor diferente al servidor web, primero tendrá que transferir el archivo por completo desde el rdbms al servidor web en lugar de transmitirlo. Sin embargo, si la capa de transporte proporciona la abstracción del sistema de archivos (que incluso NFS admite), podría buscar a la mitad del archivo e inmediatamente comenzar a transmitirlo de nuevo al cliente sin almacenar el archivo en el búfer más de lo necesario. Esto es hecho rutinariamente por el servidor webnginx , Apache , PureFTP y ProFTP.
Copia doble en el RDBMS. Por el solo hecho de que está en la base de datos, es probable que lo escriba dos veces. Una vez en un registro de escritura anticipada (WAL) y luego nuevamente en el espacio de tabla.
Sin actualizaciones, nunca MVCC significa que nada se actualiza, solo se copia nuevamente con modificaciones, y luego la fila anterior se marca como caducada (eliminada). Cualquier actualización del archivo requerirá escribir toda la fila , no solo el archivo de toda la fila. Los sistemas de archivos también pueden proporcionar esto, con registro de datos, pero rara vez lo necesita.
Lectura y transferencia de archivos para ralentizar la consulta Si el archivo en sí está almacenado en una fila que necesita consultar, toda la fila tendrá que esperar a que se transfiera el archivo o tendrá que emitir dos consultas separadas .
Uso de memoria en el cliente DB. El cliente DB (libpq, jdbc, odbc, freetds, etc.) o similar probablemente almacenará la consulta en la memoria intermedia. Cuando ese búfer en memoria se agota, puede iniciar un búfer de disco o, lo que es peor, puede volver al núcleo para ser paginado en el disco.
Consulta de estrangulamiento de muchas bases de datos proporcionan la capacidad de matar y cosechar consultas cuando toman demasiado mucho en la forma de tiempo o recursos. Tenga en cuenta que las transferencias de archivos no se detallarán en ninguna implementación. ¿Esa consulta fue asesinada después de 3 segundos? ¿O tomó 1 segundo y el backend pasó 2 segundos transfiriendo un archivo? No solo "detallado", ¿cómo va a indicar de manera efectiva cuánto tiempo debe tomar una consulta cuando el 99.9% de las consultas devuelven 1 KB y la otra devuelve 1 GB?
Sin copia en escritura o desduplicación XFS y BTRFS admiten copia en escritura y desduplicación de forma transparente. Esto significa que el sistema de archivos puede manejar de manera transparente tener la misma imagen en todas partes o necesitar una segunda copia . Sin embargo, si el archivo no está solo y está en una fila o en una tienda, es probable que el sistema de archivos no pueda deducirlo.
Integridad mucha gente aquí está hablando de integridad. ¿Qué crees que es mejor para detectar la corrupción del sistema de archivos, una aplicación que utiliza el sistema de archivos o las utilidades principales del sistema de archivos? Almacene un archivo en una fila o fuera de línea y cualquier corrupción del sistema de archivos ocultará la base de datos.
xfs_repair
es muy bueno para recuperarse cuando tiene daños en el sistema de archivos o en el disco duro, y si falla, aún será mucho más fácil hacer análisis forenses de datos.Migración en la nube si alguna vez desea almacenar los archivos en una SAN o en la nube tendrá más dificultades porque ahora esa migración de almacenamiento es una migración de base de datos. Si sus archivos se almacenan, por ejemplo, en el sistema de archivos, puede moverlos con bastante facilidad a S3 (y con algo así
s3fs
puede ser transparente).Excepciones
Almacenar archivos en la base de datos tiene algunos casos de uso válidos,
Mitigaciones
Algunas bases de datos tienen la noción de un "recurso administrado externamente" donde la base de datos administra el archivo de forma privada en el disco, como
PostgreSQL a través de la infraestructura de objetos grandes proporciona un identificador de archivo a un recurso durante la transacción.
La infraestructura de flujo de archivos de SQL Server 2017 proporciona un acceso temporal que dura la duración de la transacción que puede usar para obtener la Ruta del archivo y abrir un Identificador de archivo.
Oracle proporciona
BFILE
(esto no tiene nada que ver con sus cosas internas de LOB que se llamaSecureFile
Algunas de las bases de datos almacenan grandes objetos binarios fuera de línea o pueden, como Oracle SecureFile. Esto le permite actualizar la fila, sin reescribir el archivo.
Algunas bases de datos como Oracle hacen su MVC sin un registro WAL y no tienen que duplicar la escritura del archivo.
Algunas de las bases de datos, como SQL Server y Oracle, brindan la capacidad de "transmitir" datos del archivo sin tener que manejarlo. Esto puede o no ejecutarse en una conexión diferente a la consulta de bases de datos. Pero la clave aquí es que, si bien puede transmitir el archivo (en teoría), no puedo encontrar ninguna evidencia de ningún producto que no haya sido creado por el proveedor que usa esa función. Por ejemplo, ¿dónde está el puente NGINX / Apache para permitirle hacer esto?
Oracle proporciona deduplicación, compresión y cifrado opcionales a través del almacenamiento interno-LOB (como SecureFile).
Conclusión
El peor de los casos cuando coloca un archivo en la base de datos es muy malo para el rendimiento y la compatibilidad con las herramientas. Siempre es excepcionalmente dependiente de la implementación. De ninguna manera la base de datos es mejor para ser un sistema de archivos que el sistema de archivos. En todos los sentidos, es un compromiso e incluso cuando obtienes potentes funciones de mitigación (como el caso de SecureFile), las herramientas son tan pobres que en realidad no es mucho más que un punto de marketing a menos que el proveedor RDBMS construya toda tu pila.
Mantenlo simple, y la regla general es mantener los archivos fuera de la base de datos .
Solución
¿Cómo debe almacenar archivos o abstraer un sistema de archivos de tal manera que funcione eficazmente para múltiples inquilinos y usuarios? Soy parcial al hash del contenido del archivo. Esto es bastante común en estos días y funciona bien.
fuente
Aunque depende en parte de la aplicación / entorno (personas incluidas), iría por el blob.
Mantener todo en la base de datos significa que la replicación funciona para los datos del archivo. Necesitaría un mecanismo separado para sincronizar archivos FS.
En algunas aplicaciones, el sistema de archivos no debe modificarse de todos modos. Por ejemplo, en un sitio web de producción, evitaría usar el sistema de archivos para datos no desechables (el sitio vive bajo un SCM, datos en una base de datos).
Suponiendo que tenemos múltiples usuarios / aplicaciones con permisos separados, entonces cualquier almacenamiento del sistema de archivos brinda la oportunidad de diferencias en los derechos de acceso de DB y FS.
El refinamiento que consideraría hacer para el almacenamiento BLOB es fragmentar los datos si tiene sentido; si solo necesita 512 bytes de un BLOB de 20Mb, este acceso de tipo sectorial es una verdadera bendición, especialmente si se trata de clientes remotos (y nuevamente, una actualización parcial crea mucho menos tráfico de replicación).
fuente
Mi voto sería por ninguno de los dos. Almacene los datos en un sistema como Amazon S3 o el CDN de Microsft y almacene esa URL en la base de datos.
De esta forma, obtienes la fiabilidad de tener los datos siempre accesibles sin tener que lidiar con bases de datos de tamaño monstruoso.
fuente
Para postgres:
En realidad es sencillo. Hay un
BYTEA
tipo que se puede usar para almacenar cadenas binarias. Por defecto, no hay utilidades integradas como las mencionadas para MS u Oracle. Por lo tanto, almacenar muchos archivos grandes y recuperarlos puede ser tedioso. También debe realizar la conversión de los archivos dentro de la aplicación (como con unoByteStream
o similar, aunque no sé cómo funciona esto con las soluciones de bases de datos específicas de archivos MS- / Oracle <->). También hay unlo
tipo, que ayuda con el trabajo de administrar BLOB, ya que parte de la administración interna de estos tipos puede no realizar un seguimiento de las referencias.fuente
Comparto mi experiencia con el servidor Ms SQL y una gran cantidad de archivos. Guardamos los archivos en un servidor de archivos. La base de datos tiene dos tablas, una para las carpetas de archivos y las credenciales de acceso, una para el nombre del archivo. Es fácil mantener la base de datos y los archivos. Puede mover fácilmente los archivos, incluso cruzar los servidores, solo necesita modificar la tabla de carpetas.
fuente