¿Cuál es el mejor lugar para almacenar imágenes cargadas, bases de datos SQL o sistema de archivos de disco?


Estoy escribiendo una aplicación que permite a los usuarios cargar imágenes en el servidor. Espero alrededor de 20 imágenes por día, todas jpeg y probablemente no editadas / redimensionadas. (Esta es otra pregunta, cómo cambiar el tamaño de las imágenes en el lado del servidor antes de almacenar. Tal vez alguien puede por favor soltar un recurso. NET para eso en el comentario o así). Ahora me pregunto cuál es el mejor lugar para almacenar imágenes subidas.

  • Almacenar las imágenes como un archivo en el sistema de archivos y crear un registro en una tabla con el camino exacto a esa imagen.

  • O bien, almacene la imagen en una tabla utilizando un tipo de datos" imagen "o" datos binarios " del servidor de base de datos.

Veo ventajas y desventajas en ambos. Me gusta a) porque puedo reubicar fácilmente los archivos y solo tengo que cambiar la entrada de la tabla. Por otro lado, no me gusta almacenar datos comerciales en el servidor web y realmente no quiero conectar el servidor web a ninguna otra fuente de datos que contenga datos comerciales (por seguridad motivo) Me gusta b) porque toda la información está en un solo lugar y es fácilmente accesible por una consulta. Por otro lado, la base de datos se hará muy grande muy pronto. Subcontratar esos datos podría ser más difícil.

Author: BalusC, 2008-12-08

19 answers

Generalmente almaceno archivos en el sistema de archivos, ya que para eso está, aunque hay excepciones. Para los archivos, el sistema de archivos es la solución más flexible y eficiente (generalmente).

Hay algunos problemas con el almacenamiento de archivos en una base de datos - los archivos son generalmente mucho más grandes que su fila promedio - los conjuntos de resultados que contienen muchos archivos grandes consumirán mucha memoria. Además, si utiliza un motor de almacenamiento que emplea bloqueos de tabla para las escrituras (ISAM, por ejemplo), sus archivos la tabla puede estar bloqueada a menudo dependiendo del tamaño / velocidad de los archivos que esté almacenando allí.

Con respecto a la seguridad - normalmente almaceno los archivos en un directorio que está fuera de la raíz del documento (no accesible a través de una solicitud http) y los sirvo a través de un script que comprueba primero la autorización adecuada.

 77
Author: Eran Galperin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-08 00:03:20

El único beneficio para la opción B es tener todos los datos en un sistema, ¡sin embargo, es un beneficio falso! Puede argumentar que su código también es una forma de datos, y por lo tanto también se puede almacenar en la base de datos - ¿cómo le gustaría?

A menos que tenga algún caso único:

  • La lógica de negocio pertenece al código.
  • Los datos estructurados pertenecen a la base de datos (relacional o no relacional).
  • Los datos masivos pertenecen al almacenamiento (sistema de archivos o otro).

Archivos, Código, Datos

No es necesario usar el sistema de archivos para guardar archivos. En su lugar, puede usar almacenamiento en la nube (como Amazon S3 ) o Infraestructura como servicio (como Uploadcare):

Https://uploadcare.com/upload-api-cloud-storage-and-cdn /

Pero almacenar archivos en la base de datos es una mala idea.

 33
Author: David Avsajanishvili,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-04 21:54:00

Flickr usa el sistema de archivos-discuten las razones aquí

 20
Author: Martin Beckett,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-08 00:41:45

Hemos tenido clientes que insisten en la opción B (almacenamiento de base de datos) varias veces en diferentes backends, y siempre terminamos volviendo a la opción A (almacenamiento del sistema de archivos) eventualmente.

Grandes BLOBs como ese simplemente no han sido manejados lo suficientemente bien incluso por SQL Server 2005, que es el último en el que lo probamos.

Específicamente, vimos hinchazón grave y creo que tal vez problemas de bloqueo.

Otra nota: si está utilizando almacenamiento basado en NTFS (windows server, etc) usted podría considerar la posibilidad de encontrar una manera de poner miles y miles de archivos en un directorio. No estoy seguro de por qué, pero a veces el sistema de archivos no hace frente bien a esa situación. Si alguien sabe más sobre esto me encantaría escucharlo.

Pero siempre trato de usar subdirectorios para dividir las cosas un poco. La fecha de creación a menudo funciona bien para esto:

Imágenes/2008/12/17/.jpg

...Esto proporciona un nivel decente de separación, y también ayuda un poco durante la depuración. Los clientes Explorer y FTP por igual pueden ahogarse un poco cuando hay directorios realmente enormes.

EDIT: Solo una nota rápida para 2017, en las versiones más recientes de SQL Server, hay nuevas opciones para manejar muchos BLOBs que se supone que evitan los inconvenientes que comenté.

 10
Author: Brian MacKay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-31 13:18:57

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

Pros:

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

Contras:

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

Yo llamaría a mi implementación un éxito, se encarga de los requisitos de copia de seguridad y simplifica el diseño del proyecto. El rendimiento está bien para las 20-30 personas que utilizan el app.

 8
Author: too much php,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-08 04:29:55

Utilizo imágenes subidas en mi sitio web y definitivamente diría que la opción a).

Otra cosa que recomiendo encarecidamente es cambiar inmediatamente el nombre del archivo de lo que el usuario ha llamado a la foto, a algo más manejable. Por ejemplo, algo con la fecha y la hora para identificar de forma única cada imagen.

También ayuda a despojar el nombre del archivo del usuario de cualquier carácter extraño para evitar complicaciones futuras.

 6
Author: barfoon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-08 02:12:25

Definitivamente cambia el tamaño de la imagen, y comprueba su formato si puedes. Ha habido casos de archivos maliciosos que se cargan y sirven por anfitriones involuntarios - por ejemplo, la vulnerabilidad GIFAR le permitió ocultar un applet java malicioso en un archivo GIF, que luego sería capaz de leer las cookies en el contexto actual y enviarlas a otro sitio para un ataque de scripting entre sitios. Redimensionar las imágenes generalmente evita esto, ya que munges el código incrustado. Mientras que este ataque ha sido solucionado por parches JVM, servir ingenuamente archivos binarios sin borrarlos te abre a una amplia gama de vulnerabilidades.

Recuerde, la mayoría de los escáneres de virus solo pueden ejecutarse contra el sistema de archivos - si almacena sus binarios en la base de datos, no podrá ejecutar un escáner contra ellos muy fácilmente.

 6
Author: Tim Howland,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-11 01:21:33

Sé que este es un post antiguo. Pero muchos visitantes de esta página no están recibiendo nada relacionado con la pregunta. Especialmente para un novato.

Cómo cargar y almacenar imágenes o archivos en nuestro sitio web:

Para un sitio web estático, tal vez no haya problema, ya que el almacenamiento de archivos para algunos alojamientos compartidos sigue siendo adecuado. El problema viene de un sitio web dinámico cuando se hace más grande. Más grande en la base de datos se puede manejar, pero más grande en el archivo como imágenes se convierte en un problema. Hay dos tipos de imágenes en un sitio web:

  1. Las imágenes provienen del administrador de dynamic blog. Por lo general, estas imágenes se han optimizado antes de subir.

  2. Imágenes de los usuarios en el caso de los usuarios se permite subir imágenes como avatar. O los usuarios pueden crear contenido de blog y poner algunas imágenes desde el editor de texto. Este tipo de imágenes es difícil de predecir el tamaño. Los usuarios pueden cargar imágenes grandes solo para contenido pequeño redimensionando el tamaño de la vista pero no redimensionando el tamaño de la imagen.

Ignorando el artículo no. 1 anterior, la solución rápida para el artículo no. 2 se puede resolver temporalmente con los siguientes consejos si no tenemos la funcionalidad de image optimizer en nuestro sitio web:

  1. No permita que los usuarios carguen directamente desde el editor de texto redirigiéndolos a la galería de imágenes. En esta página los usuarios deben cargar el archivo con antelación antes de que puedan incrustarse en el contenido. Este método se llama como un Administrador de archivos.

  2. Utilice una función de recorte de imagen para que los usuarios subir imágenes. Esto limitará el tamaño de la imagen, incluso los usuarios cargan archivos muy grandes. La imagen final es el resultado de la imagen recortada. Podemos definir el tamaño en el lado del servidor y aceptar solo por ejemplo 500Kb o inferior.

Ahora, eso es solo temporal. Para la solución final, la pregunta se repite :

  • ¿Cómo manejar un gran almacenamiento de imágenes?
  • Redimensionar o cambiar la extensión.
  • Cómo un sitio web grande o mediano o comercio electrónico manejar el almacenamiento de archivos para su ¿imágenes?

Lo que podemos hacer entonces:

  1. Migrar desde el alojamiento compartido VPS. No es suficiente? Luego más alto actualizando a Dedicado.

  2. Cree su propio servidor para el almacenamiento de archivos. Buscando en Google para hacerlo. Esto no es tan difícil como crees. Algunas personas lo hacen por su sitio web.

  3. La forma más fácil es utilizar el servicio de almacenamiento de archivos CDN.

Bien, 1 y 2 es un poco caro. Pero no 3 creo que es el mejor solución.

Algunos servicios de CDN le permiten almacenar tantos archivos web como desee.

Pregunta, " ¿cómo subir un archivo a CDN desde nuestro sitio web?"

No se preocupe, una vez que se registre, generalmente gratis, obtendrá orientación sobre cómo cargar archivos y obtener su enlace desde/hacia su sitio web. Obtendrá una API y más. Es fácil.

Algunos proveedores nos ofrecen un servicio gratuito durante 14 días con almacenamiento y ancho de banda limitados. Pero eso estará bien para el punto de partida. El único problema es porque "la gente nunca lo intenta".

Espero que ayude al novato.

 5
Author: Sulung Nugroho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-07 17:09:51

La mayoría de las implementaciones son la opción A.

Con la opción B, se abre toda una gran lata de whoop4ss cuando se marshall esos bits de la base de datos en algo que se puede mostrar en un navegador... Además, si la base de datos está baja, las imágenes no están disponibles.

No creo que el espacio sea un gran problema... Las unidades de terabyte son un par de cientos de dólares ahora.

Estamos implementando con la opción A porque no tenemos el tiempo ni los recursos para hacer la opción B.

 3
Author: mson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-08 00:40:29

Para cambiar el tamaño automáticamente, pruebe imagemagick... se utiliza para muchos de los principales sistemas de gestión de contenido/fotografía de código abierto... y creo que hay algunas extensiones. net para ello.

 3
Author: jle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-08 01:58:15

Hay una especie de enfoque híbrido en SQL Server 2008 llamado el filestream datatype del que se habló en RunAs Radio #74, que es algo así como lo mejor de ambos mundos. La mayoría de la gente no tiene la otion 2008, pero si lo hace, esta opción se ve bastante bien

 3
Author: Charles Graham,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-09 05:15:10

Usamos A. Lo pondría en una unidad compartida (a menos que no planee ejecutar más de un servidor).

Si llega el momento en que esto no escalará para usted, puede investigar los mecanismos de almacenamiento en caché.

 2
Author: csexton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-08 00:03:56

Absolutamente, positivamente opción A. Otros han mencionado que las bases de datos generalmente no tratan bien con los BLOBs, estén diseñados para hacerlo o no. Los sistemas de archivos, por otro lado, viven para estas cosas. Tiene la opción de usar bandas RAID, distribuir imágenes a través de varias unidades e incluso distribuirlas a través de servidores geográficamente dispares.

Otra ventaja es que las copias de seguridad/replicación de la base de datos serían monstruosas.

 2
Author: dj_segfault,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-08 01:46:47

Opción A.

Una vez cargada la imagen, puede verificar el formato y redimensionarla antes de guardarla. Hay una serie de ejemplos de código. Net para cambiar el tamaño de las imágenes en http://www.codeproject.com . Por ejemplo: http://www.codeproject.com/KB/cs/Photo_Resize.aspx

 2
Author: Leah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-09 04:40:26

Por razones de seguridad, también es una buena práctica para evitar problemas causados por ES DECIR, el contenido Sniffing que puede permitir a los atacantes cargar JavaScript dentro de archivos de imagen, que podrían ejecutarse en el contexto de su sitio. Así que es posible que desee transformar las imágenes (recortar/redimensionarlas) de alguna manera antes de almacenarlas para evitar este tipo de ataque. Esta respuesta tiene algunas otras ideas.

 2
Author: Day,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:55:04

Bueno, tengo un proyecto similar donde los usuarios suben archivos al servidor. Bajo mi punto de vista, la opción a) es la mejor solución debido a que es más flexible. Lo que debe hacer es almacenar imágenes en una carpeta protegida clasificada por subdirectorios. El directorio principal debe ser configurado por el administrador ya que el contenido no debe ejecutar scripts (muy importante) y (leer, escribir) protegido por no ser accesible en la solicitud http.

Espero que esto te ayude.

 2
Author: domoindal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-06 14:52:17

Esto es básicamente lo que hago.

  1. Almacena una imagen cargada en un directorio temporal o memoria.
  2. Procesa esa imagen antes de almacenarla permanentemente. 2.1. Correcciones de color 2.2. Comprimir 2.3. Crear varias copias basadas en las dimensiones de la imagen 2.4. Renombrar con .xl, .lg,. md,. sm etc. sufijos
  3. Empaquete todos los archivos de imagen procesados (de un solo archivo) dentro de una carpeta con el nombre de la carpeta como id que se almacenará en la base de datos para cualquier fila/documento a lo largo con image file name (o puede ser nombre aleatorio como nombre de imagen).
  4. Crear aaaa/mm/d path carpeta si no existe. Por ejemplo 2016/08/21. Recuerde esa ruta y almacene en la base de datos para el mismo documento y fila.
  5. Mueva la carpeta image id a la carpeta path. (La carpeta Path puede estar ubicada en la carpeta/var / web-content.)
  6. Limpie el búfer de memoria o elimine el archivo temporal.

Cuando necesita acceder a cualquier imagen mencionada en un documento, tiene la ruta e id de la carpeta que contiene imágenes. Por ejemplo /var/web-content/{{path}}/{{id}}/image-file-name.sm.jpg

De esta manera, si tiene que eliminar todos los archivos de imagen procesados, simplemente elimine la carpeta y su contenido recursivamente.

 2
Author: Uday Hiwarale,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-29 16:17:13

Si son archivos pequeños que no necesitan ser editados entonces la opción B no es una mala opción. Prefiero esto a escribir lógica para almacenar archivos y lidiar con problemas de estructura de directorios locos. Tener muchos de archivos en un directorio es malo. ¿emkay?

Si los archivos son grandes o requieren una edición constante, especialmente de programas como Office, entonces la opción A es su mejor opción.

Para la mayoría de los casos, es una cuestión de preferencia, pero si vas opción A, sólo hacer re el los directorios no tienen demasiados archivos en ellos. Si elige la opción B, haga que la tabla con los datos BLOBed esté en su propia base de datos y/o grupo de archivos. Esto ayudará con el mantenimiento, especialmente copias de seguridad / restauraciones. Sus datos regulares son probablemente bastante pequeños, mientras que sus datos de imagen serán enormes con el tiempo.

 1
Author: Charles Graham,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-09 05:11:25

Depende de sus necesidades, especialmente volumen, usuarios y frecuencia de búsqueda. Pero, para oficinas pequeñas o medianas, la mejor opción es utilizar una aplicación como Apple Photos o Adobe Lighroom. Están especializados en almacenar, catalogar, indexar y organizar este tipo de recursos. Pero, para las grandes organizaciones, con fuertes requisitos de almacenamiento y un alto número de usuarios, se recomienda crear instancias de una plataforma de Gestión de Contenidos con una Gestión de Activos Digitales, como Nuxeo o Alfresco; ambos ofrece muy buenos recursos gestionar volúmenes muy grandes de datos con métodos simplificados para recuperarlos. Y, muy importante: hay una opción gratuita (código abierto) para ambas plataformas.

 1
Author: Carlos Camargo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-18 15:43:33