2012-04-16 18 views
5

Estoy construyendo una aplicación PHP que permite a los usuarios subir fotos. Para hacerlo manejable, una carpeta debe tener un máximo de 5000 fotos. A cada foto cargada se le asignará una ID en la base de datos, y la foto se renombrará como ID.PHP organizar fotos cargadas

¿Cómo puedo verificar si una determinada carpeta tiene 5000 fotos? ¿Debo verificar la identificación de la última fila en la tabla de fotos?

Las carpetas se denominarán incrementalmente. p.ej. folder_1, folder_2, etc.

Mis pasos propuestos:

  1. Recuperar la última ID de inserción del vector Photo
  2. (LAST_INSERT_ID + 1) = 5,000% Some_number (El número de la carpeta se debe guardar en)
  3. Guarde la foto en folder_some_number. Si la carpeta no existe, crea una nueva.

¿O existe una forma mejor de hacerlo?

+0

'(LAST_INSERT_ID + 1)% 5000 == 0' – PeeHaa

+0

No utilizaría el módulo si fuera tú. Si un inserto falla por alguna razón, omitirá ese número generado (al menos en MySQL) y su recuento será incorrecto. Lo almacenaría como una columna explícita en una tabla. – halfer

+0

@RepWhoringPeeHaa, No lo he pensado. Bien si el (last_insert_id + 1)% 5000 = 0, lo hará predeterminado a la carpeta 'carpeta'. La siguiente carpeta será 'folder1' – WebNovice

Respuesta

2
$last_id; // for example 9591 
$current_folder = floor($last_id/5000); 
$picture_num_in_folder = $last_id-($current_folder*5000); 
if ($picture_num_in_folder == 5000) 
    // new dir and such (new folderid = $current_folder+1 and $picture_num_in_folder = 1) 
else 
    // just place the picture with unique ID $last_id+1 called image_$picture_num_in_folder+1 in folder $current_folder 
5

Supongo que las lecturas de la base de datos van a ser más rápidas que las lecturas del sistema de archivos como esta.

Sería mejor ejecutar una consulta sql y obtener un recuento por carpeta, agrupado.

// Example Query 
SELECT COUNT(file), folderId As Count FROM photos WHERE folderId IN ('1', '2') GROUP BY folder 
// It would be beneficial to have a flag on the folders that would enable or disable them 
// that way you're not iterating through folders that we already know are > 5k 
// You would run this and have seperate query that would pull in these folder names 
// and passing them to the above query. 
SELECT foldername, folderId FROM folders WHERE countFlag = 0; 


//Example Conditional. 
if($Count > 5000): 
    // Over 5k Do Something 
    //Since were over 5k, set this folders flag to 1 
    // that way we arent iterating through it again 
    $countFlag = 1; 
else: 
    // Under 5k Do Something else 
endif; 

Nota: Si necesitas ejemplos de código reales, puedo azotar algo bien rápido. Los ejemplos anteriores dejan fuera el código de trabajo real y son solo para fines teóricos. Tendrá que recorrer las filas devueltas, ya que están agrupadas por carpeta.

+0

+1 para eso. Lo más fácil sería guardar el ID actual y el nombre de la carpeta actual en la base de datos. De esta manera, usted sabe dónde se encuentra, sin tener que hacer mucho más. – OptimusCrime

-1

si desea organizar sus carpetas y archivos de esta manera, no necesita verificar si la carpeta tiene 5000 archivos, simplemente asigne los archivos a la carpeta correspondiente.

Si hay menos de 5000 archivos en una carpeta x que deberían estar llenos (debido a que la última identificación es más grande que 5000 * x) eso significa que se han eliminado algunas imágenes. No puede reasignar esa ID a una fila en su base de datos para que no pueda volver a llenar el espacio de los archivos eliminados.

1

No utilice identificadores de autoincrement para realizar cálculos. Cuando elimines archivos, obtendrás agujeros en tus secuencias de ID que te quitarán las matemáticas. Guarde el filepath en su tabla db. A continuación, hacer un simple recuento:

SELECT filepath, COUNT(filename) AS num FROM mytable 
GROUP BY filepath; 

Puede guardar nuevos archivos de rutas de los archivos donde num < 5000.

+0

Aunque es improbable que en el escenario OPs esté haciendo 'count()' not 'sum()' no es mala idea no basar en un ID auto incrementado. Todavía usaría 'auto_increment' pero simplemente no basaría tus conteos en el ID – gorelative

+0

A menos que el OP obtuviera un alto porcentaje de operaciones DB fallidas/restituidas, es poco probable que se descarte demasiado. La intención es no exceder 5000, no ser EXACTAMENTE 5000 cada vez. –

1

Utilizando el ID de inserción podría no ser muy preciso, ya que hay una serie de condiciones de error que puede causar una ID para ser "saltado". Puede guardar el número de carpeta en una columna separada, llamada "folder_number" o similar. De esta forma puede obtener el número de carpeta más alto y luego contar el número de registros en esa carpeta, si es menor que 5000, agregarlo en la misma carpeta; de lo contrario, ejecute su lógica para incrementar el número de carpetas (creando el físico carpeta al mismo tiempo).

Eso debería ser más rápido que usar el sistema de archivos para verificar, lo que podría ser bastante lento para el volumen de los archivos que está hablando.

1

Permítanme sugerir otro enfoque: Utilice un hash de ID de la imagen y utilizar los primeros caracteres como un camino por ejemplo, supongamos el ID de imagen es 1 para los cuales el hash es c4ca4238a0b923820dcc509a6f75849b. Crea la estructura de directorios /rootpath/images/c/4/c/ y guarda la imagen en ella. Puede usar mkdir() para crear directorios anidados como mkdir('/dir/c/4/c/', 0777, true);.

De esta manera distribuye automáticamente la carga entre muchas carpetas y la propia ID es la ruta.

Si mi memoria no me falla, WordPress utiliza algo similar ...

+0

Si no me equivoco, de esta manera, terminaría con tantas carpetas. P.ej. 5000 imágenes pueden terminar en 100 carpetas? Donde, según mi requerimiento, necesitaría solo 1 carpeta. – WebNovice

+0

+1 para esto como una solución escalable. Asegura que las carpetas no se llenen demasiado y, cuando la situación así lo exija, el almacenamiento del archivo se puede dividir entre máquinas físicas asignando diferentes rutas. @Damchey - no debe preocuparse por tener muchas carpetas - en el servidor, no las explorará manualmente a través de ssh/gui. – halfer

+0

@Damchey, terminará con varios directorios pero esta estructura equilibrará la cantidad de archivos en ellos de una manera que no requerirá que administre la cantidad de archivos por directorio. En general, cuantos más archivos tenga en un solo directorio, más tiempo requerirá que el sistema de archivos recupere un archivo de ese directorio. – Yaniro

Cuestiones relacionadas