sintaxis que insertar guardar desde descargar como campo archivos archivo almacenar php mysql streaming http-headers blob

php - insertar - que es un campo blob en mysql



MySQL Binary Storage usando el sistema de archivos BLOB VS OS: archivos grandes, grandes cantidades, grandes problemas (1)

Versiones que estoy ejecutando (básicamente las últimas de todo):
PHP: 5.3.1
MySQL: 5.1.41
Apache: 2.2.14
OS: CentOS (más reciente)

Aquí está la situación.

Tengo miles de documentos muy importantes, que van desde contratos con clientes hasta firmas de voz (grabaciones de autorización de clientes para contratos), con tipos de archivos que incluyen, entre otros, archivos jpg, gif, png, tiff, doc, docx, xls, wav, mp3 , pdf, etc.

Todos estos documentos se almacenan actualmente en varios servidores, incluidos Windows 32 bit, CentOS y Mac, entre otros. Algunos archivos también se almacenan en computadoras de escritorio y computadoras portátiles de los empleados, y algunos todavía son copias impresas almacenadas en cientos de cajas y archivadores.

Ahora, debido a que los clientes o los abogados pueden exigir pruebas de contratos en cualquier momento, mi empresa debe poder buscar y ubicar los documentos correctos de manera efectiva, por esta razón TODOS estos archivos deben digitalizarse (si no lo están ya) y estar correlacionados en algún tipo de orden para buscar y acceder.

Como programador, he creado una herramienta completa de gestión de relaciones con el cliente que utiliza toda la empresa. Esto incluye la administración de perfiles de clientes, herramientas de seguimiento de pedidos y trabajos, módulos de administración y creación de trabajos / ventas, etc., y en este momento cualquier archivo que se necesite a nivel de perfil de cliente (licencia de conducir, autoridad de crédito, etc.) o en un trabajo / El nivel de venta (contratos, firmas de voz, etc.) se puede cargar en el servidor y se encuentra en una estructura jerárquica principal / secundaria, al igual que el Explorador de Windows o cualquier otro modelo típico de administración de archivos.

La estructura aparece como tal:

Licencia de conducir
| - DL_123.jpg
voz_signaturas
| - VS_123.wav
| - VS_4567.wav
contratos

Por lo tanto, los archivos se actualizan mediante PHP y Apache, y se almacenan en el sistema de archivos del sistema operativo. En el momento de la carga, cierta información sobre el archivo (s) se almacena en una base de datos MySQL. Parte de la información almacenada es:

TABLA: FileUploads
ID de archivo
CustomerID (el ID de cliente al que pertenece el archivo, todos tienen esto).
JobID / SaleID (el ID del trabajo / venta asociado, si corresponde)
Tamaño del archivo
Tipo de archivo
UploadedDateTime
Subido por
FilePath (la ruta del directorio donde se almacena el archivo.)
Nombre de archivo (nombre de archivo actual del archivo cargado, combinación de CustomerID y JobID / SaleID, si corresponde)
Descripción del archivo
OriginalFileName (nombre original del archivo de origen cuando se carga, incluida la extensión.)

Como puede ver, el archivo está vinculado a la base de datos por el nombre del archivo. Cuando quiero proporcionar los archivos de un cliente para descargar a un usuario, todo lo que tengo que hacer es "SELECCIONAR * DE FileUploads WHERE CustomerID = 123 O JobID = 2345;" y esto dará como resultado todos los detalles del archivo que requiero, y con FilePath y FileName puedo proporcionar el enlace para descargar.

http ... server / FilePath / FileName

Hay varios problemas con este método:

  1. El almacenamiento de archivos en este entorno "inconsciente de base de datos" significa que no se mantiene la integridad de los datos. Si se elimina un registro, el archivo no se puede eliminar también, o viceversa.
  2. Los archivos están esparcidos por todo el lugar, diferentes servidores, computadoras, etc.
  3. El nombre del archivo es lo ÚNICO que hace coincidir el binario con la base de datos, el perfil del cliente y los registros del cliente.

etc, etc. Hay muchas razones, algunas de las cuales se describen aquí: http://www.dreamwerx.net/site/article01 . También hay un artículo interesante aquí también: sietch.net/ViewNewsItem.aspx?NewsItemID=124.

Entonces, después de mucha investigación, he decidido bastante que voy a almacenar TODOS estos archivos en la base de datos, como BLOB o LONGBLOB, pero todavía hay muchas consideraciones antes de hacer esto.

Sé que almacenarlos en la base de datos es una opción viable, sin embargo, existen varios métodos para almacenarlos. También sé que almacenarlos es una cosa; correlacionar y acceder a ellos de una manera manejable es otra cosa completamente.

El artículo proporcionado en este enlace: dreamwerx.net/site/article01 describe una manera de dividir los archivos binarios cargados en trozos de 64 kb y almacenar cada fragmento con el ID de archivo, y luego transmitir el archivo binario real al cliente mediante encabezados. Esta es una idea realmente genial ya que alivia la presión en la memoria de los servidores; En lugar de cargar un archivo completo de 100 mb en la RAM y luego enviarlo al cliente, lo hace a 64 kb a la vez. He intentado esto (y he actualizado sus scripts) y esto es totalmente exitoso, en un marco de prueba muy pequeño.

Entonces, si está de acuerdo en que este método es una opción viable, estable y robusta a largo plazo para almacenar archivos moderadamente grandes (de 1 kb a un par de cientos de megas) y grandes cantidades de estos archivos, hágame saber qué otras consideraciones o ideas tiene. .

Además, estoy considerando obtener un script PHP "Administración de archivos" actual que proporcione una interfaz para administrar archivos almacenados en el Sistema de archivos y convertirlos para administrar archivos almacenados en la base de datos. Si ya hay algún software que haga esto, hágamelo saber.

Supongo que hay muchas preguntas que podría hacer, y toda la información está ahí arriba ^^ así que, por favor, discuta todos los aspectos de esto y podemos pasar ideas de un lado a otro y enseñarnos unos a otros.

Aclamaciones,

Quantico773


Trabajo en un gran sistema de software que ha hecho ambos mecanismos para almacenar archivos adjuntos y otro contenido. La primera iteración del sistema almacenó todos los datos en BLOB en la base de datos. La maldije en ese momento. Como programador, podría escribir guiones laterales para operar inmediatamente en los datos y cambiarlos cuando quisiera.

Avancé unos 10 años y todavía administro el mismo software, pero la arquitectura ha cambiado y se escribió con los punteros del sistema de archivos. Lo maldigo ahora y deseo que estuviera de nuevo en el DB. Tengo el beneficio adicional de varios años y, después de haber trabajado esta aplicación con mucha mayor capacidad en muchas más situaciones, creo que ahora mi opinión está mejor educada. La promoción o migración del sistema de la aplicación requiere secuencias de comandos y copia extensas de millones de archivos. En una ocasión cambiamos el sistema operativo y todos los punteros de archivo tenían el separador de directorio incorrecto, o el nombre del servidor cambia donde estaba el archivo y tuvimos que escribir y programar sentencias de actualización de SQL simples con el DBA el fin de semana para corregirlas. Otra es que el sistema de archivos y los registros de la base de datos se desincronizan, por lo que es incierto, pero después de miles de días de funcionamiento, a veces los sistemas no transaccionales (el sistema de archivos y la base de datos no comparten contextos transaccionales) simplemente se desincronizan. A veces los archivos desaparecen misteriosamente.

Cuando todo esto estaba en la base de datos, la migración o la promoción del entorno era una cuestión de volcar e importar la base de datos. Los cambios de fila podrían auditarse correctamente, todo lo que esté en sincronización y los registros se pueden reproducir en un momento dado si es necesario. Claro que la base de datos se hace grande, pero es 2011 y esto simplemente no es un desafío para las bases de datos.

Por lo que vale la pena, tuvimos algunos problemas similares con grandes búferes de datos al transmitir algunos datos, pero A) podríamos bombear los datos en búferes de bytes con el Input | OutputStreams en JDBC y B) al usar otras herramientas, escribimos un procedimiento almacenado eso dividiría el BLOB en una tabla temporal y serviría iterativamente a los fragmentos de la tabla temporal. Funciona genial.

No me importa cuál sea la razón técnica para no poner estas cosas en la base de datos, pero es mucho más fácil de administrar en una ubicación consolidada. Podría duplicar y triplicar el hardware o la cuadrícula de la DB por el tiempo perdido por los consultores y clientes. en un corto periodo de tiempo gestionando los archivos dispares.

Actualización: no se preocupe por los comentaristas, solo están dando su opinión al respecto.