Almacenar imágenes en DB – ¿Sí o No?

Así que estoy usando una aplicación que almacena imágenes en gran medida en la base de datos. ¿Cuál es tu punto de vista sobre esto? Soy más un tipo para almacenar la ubicación en el sistema de archivos, que almacenarla directamente en el DB.

¿Cuáles crees que son los pros / contras?

Estoy a cargo de algunas aplicaciones que administran muchos TB de imágenes. Hemos encontrado que almacenar rutas de archivos en la base de datos es lo mejor.

Hay un par de problemas:

  • el almacenamiento de la base de datos suele ser más costoso que el almacenamiento del sistema de archivos
  • puede acelerar súper-aceleradamente el acceso al sistema de archivos con productos estándar disponibles en el mercado
    • por ejemplo, muchos servidores web utilizan la llamada al sistema sendfile () del sistema operativo para enviar de forma asíncrona un archivo directamente desde el sistema de archivos a la interfaz de red. Las imágenes almacenadas en una base de datos no se benefician de esta optimización.
  • cosas como servidores web, etc., no necesitan una encoding o procesamiento especial para acceder a las imágenes en el sistema de archivos
  • las bases de datos ganan donde la integridad transaccional entre la imagen y los metadatos es importante.
    • es más complejo administrar la integridad entre los metadatos de db y los datos del sistema de archivos
    • es difícil (dentro del contexto de una aplicación web) garantizar que los datos se hayan descargado al disco en el sistema de archivos

Como con la mayoría de los problemas, no es tan simple como parece. Hay casos en los que tendría sentido almacenar las imágenes en la base de datos.

  • Está almacenando imágenes que cambian dinámicamente, por ejemplo, facturas, y desea obtener una factura tal como estaba el 1 de enero de 2007.
  • El gobierno quiere que mantengas 6 años de historia
  • Las imágenes almacenadas en la base de datos no requieren una estrategia de respaldo diferente. Las imágenes almacenadas en el sistema de archivos hacen
  • Es más fácil controlar el acceso a las imágenes si están en una base de datos. Los administradores inactivos pueden acceder a cualquier carpeta en el disco. Se necesita un administrador realmente decidido para ir a husmear en una base de datos para extraer las imágenes

Por otro lado, hay problemas asociados

  • Requerir código adicional para extraer y transmitir las imágenes
  • La latencia puede ser más lenta que el acceso directo a archivos
  • Mayor carga en el servidor de la base de datos

Archivo de la tienda. Los ingenieros de Facebook tuvieron una gran conversación al respecto. Una de las ventajas era conocer el límite práctico de los archivos en un directorio.

Aguja en un pajar: almacenamiento eficiente de miles de millones de fotos

Esto podría ser una posibilidad remota, pero si está utilizando (o planea usar) SQL Server 2008, le recomendaría echar un vistazo al nuevo tipo de datos de FileStream .

FileStream resuelve la mayoría de los problemas relacionados con el almacenamiento de los archivos en la base de datos:

  1. Los Blobs en realidad se almacenan como archivos en una carpeta.
  2. Se puede acceder a los Blobs usando una conexión de base de datos o sobre el sistema de archivos.
  3. Las copias de seguridad están integradas.
  4. La migración “simplemente funciona”.

Sin embargo, el “Cifrado de datos transparente” de SQL no encripta los objetos de FileStream, por lo que si eso es una consideración, es mejor que los guarde solo como varbinary.

Del artículo de MSDN:

Las instrucciones de Transact-SQL pueden insertar, actualizar, consultar, buscar y hacer una copia de seguridad de los datos de FILESTREAM. Las interfaces del sistema de archivos Win32 proporcionan acceso continuo a los datos.
FILESTREAM utiliza la memoria caché del sistema NT para almacenar datos de archivos en caché. Esto ayuda a reducir cualquier efecto que los datos de FILESTREAM puedan tener en el rendimiento del motor de base de datos. El grupo de búferes de SQL Server no se usa; por lo tanto, esta memoria está disponible para el procesamiento de consultas.

Las rutas de archivos en DB son definitivamente el camino a seguir. He escuchado historia tras historia de clientes con TB de imágenes que se convirtió en una pesadilla tratar de almacenar cualquier cantidad significativa de imágenes en una base de datos. El rendimiento solo es demasiado.

En mi experiencia, a veces la solución más simple es nombrar las imágenes de acuerdo con la clave principal . Por lo tanto, es fácil encontrar la imagen que pertenece a un registro en particular, y viceversa. Pero al mismo tiempo no está almacenando nada sobre la imagen en la base de datos.

El truco aquí es no convertirse en un fanático.

Una cosa a tener en cuenta aquí es que nadie en el campo del sistema de archivos pro ha enumerado un sistema de archivos en particular. ¿Significa esto que todo, desde FAT16 a ZFS, supera a todas las bases de datos?

No.

La verdad es que muchas bases de datos superan a muchos sistemas de archivos, incluso cuando solo hablamos de velocidad bruta.

El curso de acción correcto es tomar la decisión correcta para su escenario preciso, y para hacerlo, necesitará algunos números y algunas estimaciones de caso de uso.

En lugares donde DEBE garantizar la integridad referencial y el cumplimiento de ACID, se requiere el almacenamiento de imágenes en la base de datos.

No se puede garantizar transaccionalmente que la imagen y los metadatos sobre esa imagen almacenados en la base de datos se refieran al mismo archivo. En otras palabras, es imposible garantizar que el archivo en el sistema de archivos solo se altere al mismo tiempo y en la misma transacción que los metadatos.

Como otros han dicho, SQL 2008 viene con un tipo Filestream que le permite almacenar un nombre de archivo o identificador como un puntero en el archivo db y almacena automáticamente la imagen en su sistema de archivos, que es un gran escenario.

Si estás en una base de datos anterior, diría que si la estás almacenando como datos de blobs, entonces realmente no obtendrás nada de la base de datos en la forma de buscar funciones, por lo que probablemente sea la mejor. para almacenar una dirección en un sistema de archivos, y almacenar la imagen de esa manera.

De esta forma, también ahorrará espacio en su sistema de archivos, ya que solo va a guardar la cantidad exacta de espacio, o incluso el espacio compacto en el sistema de archivos.

Además, puede optar por guardar con alguna estructura o elementos que le permitan explorar las imágenes sin formato en su sistema de archivos sin hits de DB, o transferir los archivos a granel a otro sistema, disco duro, S3 u otro escenario, actualizando la ubicación en su progtwig, pero mantenga la estructura, de nuevo sin demasiado éxito tratando de sacar las imágenes de su base de datos cuando intente boost el almacenamiento.

Probablemente, también le permita arrojar algo de elemento de almacenamiento en caché, basado en urls de imágenes comúnmente afectadas en su motor / progtwig web, para que también se guarde allí.

Pequeñas imágenes estáticas (no más de un par de megas) que no se editan con frecuencia, deben almacenarse en la base de datos. Este método tiene varios beneficios que incluyen una portabilidad más sencilla (las imágenes se transfieren con la base de datos), una copia de seguridad / restauración más sencilla (las imágenes se respaldan con la base de datos) y una mejor escalabilidad (una carpeta de sistema de archivos con miles de pequeños archivos de miniaturas suena como una pesadilla de escalabilidad yo).

Servir imágenes desde una base de datos es fácil, solo implemente un controlador http que sirva la matriz de bytes devuelta desde el servidor de BD como una secuencia binaria.

Aquí hay un libro blanco interesante sobre el tema.

Para BLOB o No para BLOB: almacenamiento de objetos grandes en una base de datos o un sistema de archivos

La respuesta es, depende.” Ciertamente, dependería del servidor de la base de datos y su enfoque para el almacenamiento blob. También depende del tipo de datos almacenados en blobs, así como de cómo se debe acceder a esos datos.

Los archivos de menor tamaño se pueden almacenar y entregar de manera eficiente utilizando la base de datos como mecanismo de almacenamiento. Los archivos más grandes probablemente se almacenarían mejor utilizando el sistema de archivos, especialmente si se modificarán / actualizarán con frecuencia. (La fragmentación de blob se convierte en un problema con respecto al rendimiento).

Aquí hay un punto adicional a tener en cuenta. Una de las razones que respaldan el uso de una base de datos para almacenar los blobs es el cumplimiento de ACID. Sin embargo, el enfoque que utilizaron los evaluadores en el libro blanco (opción Bulk Logged de SQL Server) que duplicó el rendimiento de SQL Server, cambió efectivamente la ‘D’ en ACID a ‘d’, ya que los datos de blob no se registraron las escrituras iniciales para la transacción. Por lo tanto, si el cumplimiento de ACID completo es un requisito importante para su sistema, reduzca a la mitad las cifras de rendimiento de SQL Server para las escrituras de la base de datos al comparar E / S de archivo con E / S de blob de base de datos.

Una cosa que no he visto a nadie mencionar pero que definitivamente vale la pena mencionar es que también hay problemas asociados con el almacenamiento de grandes cantidades de imágenes en la mayoría de los sistemas de archivos. Por ejemplo, si toma el enfoque mencionado anteriormente y nombra cada archivo de imagen después de la clave principal, en la mayoría de los sistemas de archivos se encontrará con problemas si intenta colocar todas las imágenes en un gran directorio una vez que alcanza una gran cantidad de imágenes ( por ejemplo, en los cientos de miles o millones).

Una vez que la solución común a esto es sacarlos a un árbol equilibrado de subdirectorios.

Algo que nadie ha mencionado es que la BD garantiza acciones atómicas, integridad transaccional y trata con la concurrencia. Incluso referencialmente, la integridad está fuera de la ventana con un sistema de archivos. Entonces, ¿cómo sabe que los nombres de sus archivos realmente siguen siendo correctos?

Si tiene sus imágenes en un sistema de archivos y alguien está leyendo el archivo mientras está escribiendo una nueva versión o incluso borrando el archivo, ¿qué ocurre?

Usamos blobs porque son más fáciles de administrar (copia de seguridad, replicación, transferencia) también. Ellos trabajan bien para nosotros

El problema con el almacenamiento de solo rutas de archivo a imágenes en una base de datos es que la integridad de la base de datos ya no se puede forzar.

Si la imagen real apuntada por la ruta del archivo deja de estar disponible, la base de datos involuntariamente tiene un error de integridad.

Dado que las imágenes son los datos reales que se buscan, y que se pueden gestionar más fácilmente (las imágenes no desaparecerán de repente) en una base de datos integrada en lugar de tener que interactuar con algún tipo de sistema de archivos (si se accede al sistema de archivos de forma independiente, las imágenes PODRÍAN “desaparecer” repentinamente), iría por almacenarlas directamente como un BLOB o tal.

En una empresa donde solía trabajar, almacenamos 155 millones de imágenes en una base de datos Oracle 8i (luego 9i). Vale 7.5TB

Normalmente, estoy en contra de tomar la parte más costosa y más difícil de escalar de su infraestructura (la base de datos) y poner toda la carga en ella. Por otro lado: simplifica en gran medida la estrategia de respaldo, especialmente cuando tienes múltiples servidores web y necesitas mantener sincronizados los datos de alguna manera.

Como la mayoría de las otras cosas, depende del tamaño esperado y del presupuesto.

Hemos implementado un sistema de procesamiento de imágenes de documentos que almacena todas sus imágenes en campos de blobs de SQL2005. Hay varios cientos de GB en este momento y estamos viendo excelentes tiempos de respuesta y poca o ninguna degradación del rendimiento. Además, con respecto al cumplimiento normativo, contamos con una capa de middleware que archiva los documentos publicados recientemente en un sistema jukebox óptico que los expone como un sistema de archivos NTFS estándar.

Estamos muy contentos con los resultados, particularmente con respecto a:

  1. Facilidad de replicación y respaldo
  2. Posibilidad de implementar fácilmente un sistema de control de versiones de documentos

Si se trata de una aplicación basada en la web, puede haber ventajas para almacenar las imágenes en una red de entrega de almacenamiento de terceros, como Amazon S3 o la plataforma Nirvanix.

Suposición: la aplicación está habilitada para la web / basada en la web

Me sorprende que nadie haya mencionado esto realmente … delegarlo a otros que son especialistas -> utilizar un proveedor de alojamiento de imágenes / archivos de terceros .

Almacene sus archivos en un servicio en línea pago como

  • Amazon S3
  • Moso Cloud Storage

Otros hilos de StackOverflow hablan de esto aquí .

Este hilo explica por qué debería usar un proveedor de hosting de terceros.

Vale la pena. Lo almacenan de manera eficiente. No se carga ningún ancho de banda de sus servidores a las solicitudes de los clientes, etc.

Si no está en SQL Server 2008 y tiene algunas razones sólidas para colocar archivos de imágenes específicos en la base de datos, puede tomar el enfoque de “ambos” y usar el sistema de archivos como caché temporal y usar la base de datos como depósito principal. .

Por ejemplo, su lógica comercial puede verificar si existe un archivo de imagen en el disco antes de servirlo, y recuperarlo de la base de datos cuando sea necesario. Esto le permite la capacidad de múltiples servidores web y menos problemas de sincronización.

No estoy seguro de cuánto de este sea el ejemplo del “mundo real”, pero actualmente tengo una aplicación que almacena detalles para un juego de cartas intercambiables, incluidas las imágenes de las cartas. De acuerdo, el recuento de registros para la base de datos solo es 2851 registros hasta la fecha, pero dado el hecho de que ciertas tarjetas se liberaron varias veces y tienen ilustraciones alternativas, en realidad fue más eficiente escanear el “cuadrado principal” de la ilustración y luego dinámicamente genere el borde y efectos diversos para la tarjeta cuando se solicite.

El creador original de esta biblioteca de imágenes creó una clase de acceso a datos que representa la imagen en función de la solicitud, y lo hace bastante rápido para ver y una tarjeta individual.

Esto también facilita la implementación / actualizaciones cuando se lanzan nuevas tarjetas, en lugar de comprimir una carpeta completa de imágenes y enviarlas por el conducto y asegurar que se cree la estructura de carpetas adecuada, simplemente actualizo la base de datos y hago que el usuario la descargue nuevamente. Actualmente, este tamaño es de hasta 56 MB, lo que no es genial, pero estoy trabajando en una función de actualización incremental para futuras versiones. Además, hay una versión de “no imágenes” de la aplicación que permite que aquellos que se conectan por discado obtengan la aplicación sin demora en la descarga.

Esta solución ha funcionado muy bien hasta la fecha, ya que la aplicación en sí está dirigida como una sola instancia en el escritorio. Hay un sitio web donde todos estos datos están archivados para el acceso en línea, pero de ninguna manera usaría la misma solución para esto. Estoy de acuerdo en que el acceso al archivo sería preferible porque se escalaría mejor a la frecuencia y el volumen de las solicitudes que se realizan para las imágenes.

Espero que esto no sea demasiado parloteo, pero vi el tema y quise brindar algunas de mis ideas de una aplicación de pequeña y mediana escala relativamente exitosa.

SQL Server 2008 ofrece una solución que tiene lo mejor de ambos mundos: el tipo de datos filestream .

Administre como una tabla regular y tenga el rendimiento del sistema de archivos.

Depende de la cantidad de imágenes que va a almacenar y también de sus tamaños. He usado bases de datos para almacenar imágenes en el pasado y mi experiencia ha sido bastante buena.

IMO, Ventajas de usar la base de datos para almacenar imágenes son,

A. No necesitas estructura FS para guardar tus imágenes
B. Los índices de base de datos funcionan mejor que los árboles de FS cuando se debe almacenar más cantidad de elementos
C. Base de datos ajustada inteligentemente realiza un buen trabajo en el almacenamiento en caché de los resultados de la consulta
D. Las copias de seguridad son simples. También funciona bien si tiene configurada la replicación y el contenido se entrega desde un servidor cercano al usuario. En tales casos, no se requiere sincronización explícita.

Si sus imágenes van a ser pequeñas (digamos <64k) y el motor de almacenamiento de su db admite BLOB en línea (en registro), mejora el rendimiento aún más ya que no se requiere direccionamiento indirecto (se logra la ubicación de referencia).

Almacenar imágenes puede ser una mala idea cuando se trata de pequeñas cantidades de imágenes de gran tamaño. Otro problema con el almacenamiento de imágenes en db es que, metadatos como la creación, las fechas de modificación deben ser manejadas por su aplicación.

Recientemente he creado una aplicación PHP / MySQL que almacena archivos PDF / Word en una tabla MySQL (tan grande como 40 MB por archivo hasta el momento).

Pros:

  • Los archivos cargados se replican en el servidor de respaldo junto con todo lo demás, no se necesita una estrategia de respaldo separada (tranquilidad).
  • Configurar el servidor web es un poco más simple porque no necesito tener una carpeta de carga / uploads y decirle a todas mis aplicaciones dónde está.
  • Puedo usar transacciones para ediciones para mejorar la integridad de los datos. No tengo que preocuparme por los archivos huérfanos y perdidos.

Contras:

  • mysqldump ahora lleva mucho tiempo porque hay 500 MB de datos de archivo en una de las tablas.
  • En general, no es muy eficiente en cuanto a memoria / CPU en comparación con el sistema de archivos

Llamaría a mi implementación un éxito, se ocupa de los requisitos de copia de seguridad y simplifica el diseño del proyecto. El rendimiento está bien para las 20-30 personas que usan la aplicación.

En mi experiencia, tuve que gestionar ambas situaciones: imágenes almacenadas en la base de datos e imágenes en el sistema de archivos con ruta almacenada en db.

La primera solución, imágenes en la base de datos, es algo “más limpia” ya que su capa de acceso a los datos tendrá que ocuparse solo de los objetos de la base de datos; pero esto es bueno solo cuando tienes que lidiar con números bajos.

Obviamente, el rendimiento de acceso a la base de datos cuando se trata de objetos grandes binarios se está degradando y las dimensiones de la base de datos crecerán mucho, causando nuevamente pérdidas de rendimiento … y normalmente el espacio de la base de datos es mucho más caro que el espacio del sistema de archivos.

Por otro lado, tener grandes objetos binarios almacenados en el sistema de archivos hará que tengas planes de copia de seguridad que tengan que considerar tanto la base de datos como el sistema de archivos, y esto puede ser un problema para algunos sistemas.

Otra razón para ir al sistema de archivos es cuando tienes que compartir tus datos de imágenes (o sonidos, videos, lo que sea) con acceso de terceros: en este momento estoy desarrollando una aplicación web que usa imágenes a las que se debe acceder desde “afuera “mi granja web de tal manera que el acceso a una base de datos para recuperar datos binarios es simplemente imposible. Entonces, a veces también hay consideraciones de diseño que lo llevarán a elegir.

Tenga en cuenta también que, al hacer esta elección, si tiene que tratar con permisos y autenticación al acceder a objetos binarios: estos requisitos normalmente se pueden resolver de una manera más fácil cuando los datos se almacenan en db.

Una vez trabajé en una aplicación de procesamiento de imágenes. Almacenamos las imágenes cargadas en un directorio que era algo así como / images / [fecha de hoy] / [número de identificación]. Pero también extrajimos los metadatos (datos exif) de las imágenes y los almacenamos en la base de datos, junto con una marca de tiempo y demás.

En un proyecto anterior, almacenaba imágenes en el sistema de archivos, y eso causaba muchos dolores de cabeza con las copias de seguridad, la replicación y el sistema de archivos que se desincronizaba con la base de datos.

En mi último proyecto, estoy almacenando imágenes en la base de datos y guardándolas en caché en el sistema de archivos, y funciona muy bien. No he tenido problemas hasta ahora.

En segundo lugar, la recomendación sobre rutas de archivos. Trabajé en un par de proyectos que necesitaban administrar colecciones de activos grandes, y cualquier bash de almacenar cosas directamente en la base de datos resultó en dolor y frustración a largo plazo.

El único “verdadero” real en el que puedo pensar con respecto al almacenamiento en la base de datos es el potencial de los activos de imagen individuales. Si no hay rutas de archivos para usar, y todas las imágenes se transmiten directamente desde la base de datos, no hay peligro de que el usuario encuentre archivos a los que no deberían tener acceso.

Sin embargo, parece que sería mejor resolverlo con una secuencia de comandos intermedia que extraiga datos de una tienda de archivos inaccesible a través de la web. Entonces, el almacenamiento de DB no es REALMENTE necesario.

La palabra en la calle es que a menos que seas un proveedor de bases de datos tratando de demostrar que tu base de datos puede hacerlo (como, por ejemplo, Microsoft jactándose de que Terraserver almacena un montón de imágenes en SQL Server) no es una muy buena idea. Cuando la alternativa es almacenar imágenes en servidores de archivos y rutas en la base de datos es mucho más fácil, ¿para qué molestarse? Los campos de Blob son algo así como las capacidades todoterreno de los SUV: la mayoría de las personas no los usa, aquellos que generalmente se meten en problemas, y luego están los que sí lo hacen, pero solo por el gusto de hacerlo.

Almacenar una imagen en la base de datos todavía significa que los datos de la imagen terminan en algún lugar del sistema de archivos, pero se oscurecen, por lo que no puede acceder a ellos directamente.

+ ves:

  • integridad de la base
  • es fácil de administrar ya que no tiene que preocuparse por mantener el sistema de archivos sincronizado cuando se agrega o borra una imagen

-ves:

  • penalización de rendimiento: una búsqueda de base de datos suele ser más lenta que una búsqueda en el sistema de archivos
  • no puedes editar la imagen directamente (recortar, redimensionar)

Ambos métodos son comunes y practicados. Eche un vistazo a las ventajas y desventajas. De cualquier manera, tendrá que pensar en cómo superar las desventajas. Almacenar en una base de datos generalmente significa ajustar los parámetros de la base de datos e implementar algún tipo de almacenamiento en caché. El uso de un sistema de archivos requiere que encuentre una forma de mantener la sistema de archivos + base de datos sincronizada.