Foros del Web » Programando para Internet » PHP »

Duda sobre rendimiento en consultas anidadas...

Estas en el tema de Duda sobre rendimiento en consultas anidadas... en el foro de PHP en Foros del Web. Buenas a todo el mundo. Tengo que representar un sistema de archivos para una web. La idea genérica es sencilla, son carpetas que pueden almacenar ...
  #1 (permalink)  
Antiguo 10/07/2004, 18:37
Avatar de zarate  
Fecha de Ingreso: septiembre-2001
Ubicación: Madrid
Mensajes: 164
Antigüedad: 22 años, 7 meses
Puntos: 0
Duda sobre rendimiento en consultas anidadas...

Buenas a todo el mundo.

Tengo que representar un sistema de archivos para una web. La idea genérica es sencilla, son carpetas que pueden almacenar otras carpetas.

En la tabla de las carpetas, cada carpeta tien un campo "id_parent" que especifica cual es la carpeta "padre" o carpeta que contiene a la carpeta en cuestión (será 0 si una de las carpetas maestras o generales).

El problema viene cuando quiero hacer los típicos breadCrumbs del estilo:

Está usted en: General -> Carpeta 1 -> Carpeta 2

Mi duda de cómo resolverlo está entre:

Método 1: Crear un campo nuevo a cada carpeta en el que guarde esta información. Se trataría de, durante el proceso de alta, almacenar en un array las carpetas por las que va pasando hasta llegar al alta. No me gusta mucho porque en realidad se está duplicando la información de la base por un lado, y por otro, un cambio de estructuras de las carpetas implicaría aplicar el cambio de información en muchos registros de la base.

Método 2: Empezar a recorrer con un for las carpetas "padre" de la actual hasta llegar a una con id_parent = 0. Me parece el método más limpio, pero no sé si puede consumir demasiados recursos.... Realmente no creo que vaya a haber más de 10 niveles en ningún caso, pero el sistema debe estar preparado para que sí.

Pues si tenéis alguna recomendación o experiencia con esto os lo agradecería mucho.

Un saludo!
__________________
Zárate
  #2 (permalink)  
Antiguo 11/07/2004, 03:00
Avatar de sism82  
Fecha de Ingreso: octubre-2003
Ubicación: Guadalajara
Mensajes: 865
Antigüedad: 20 años, 6 meses
Puntos: 1
dejaselo a PHP no a la base de datos

Cita:
Iniciado por zarate
Está usted en: General -> Carpeta 1 -> Carpeta 2
A ver... para llegar a la carpeta 2, el usuario forzosamente debió haber pasado por la general y luego la carpeta 1 correcto?

no es necesario siquiera recorrer nada con un for, simplemente cuando el usuario entre a carpeta general, guarda ese nombre de carpeta en una variable de sesión tipo arreglo. Si sube de nivel elimina la última variable del arreglo. Si se adentra mas en el nivel, agrega otro elemento al final del arreglo con el nombre de la nueva carpeta.

previamente defines el arreglo
Código PHP:
$_SESSION['carpetas'] = array(); 
cuando entra a general:
Código PHP:
$_SESSION['carpetas'][] = 'General'
cuando entra a carpeta 1
Código PHP:
$_SESSION['carpetas'][] = 'Carpeta1'
si sube de nivel simplemente eliminas el último elemento con array_splice() o array_pop() o alguna otra función propia. Si baja de nivel sigues agregando elementos al arreglo.

Lo recomendable sería que hicieras un objeto que te manejara todo esto, identificar la acción (subir o bajar de nivel) y realizar el ajuste correspondiente. Si de repente sube dos niveles borrar dos elementos etc etc...

Alguna otra idea?

saludos
  #3 (permalink)  
Antiguo 11/07/2004, 03:14
Avatar de zarate  
Fecha de Ingreso: septiembre-2001
Ubicación: Madrid
Mensajes: 164
Antigüedad: 22 años, 7 meses
Puntos: 0
Cita:
Iniciado por sism82
para llegar a la carpeta 2, el usuario forzosamente debió haber pasado por la general y luego la carpeta 1 correcto?
Error.... este es el problema. Los usuarios no tienen por qué hacer la navegación "lógica" y pasar primero por todas las carpetas padre para llegar a una concreta.

Seguramente accedan directamente a una y hay que saber cuales son sus padres. Esto también es muy posible que pase porque se la pueden añadir a sus favoritos....

No me vale lo que propones, pero gracias.

¿Alguna idea más?
__________________
Zárate
  #4 (permalink)  
Antiguo 12/07/2004, 15:10
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 22 años, 3 meses
Puntos: 129
Tal vez este tutorial te ayude:
http://www.sitepoint.com/print/hiera...-data-database

Trata sobre como gestionar datos de forma gerárquica (en estructura de arbol) y los ejemplos de como recorrer ramas, .. tener en cuenta nudos y demás historias.

Un saludo,
  #5 (permalink)  
Antiguo 12/07/2004, 15:14
Avatar de sism82  
Fecha de Ingreso: octubre-2003
Ubicación: Guadalajara
Mensajes: 865
Antigüedad: 20 años, 6 meses
Puntos: 1
a ver.... entonces como accedes a las carpetas internas sin acceder directa o indirectamente a las carpetas padre?

es decir, como diferencias entre carpetapadre1->micarpeta
y carpetapadre2->micarpeta

ambas carpetas hijas se llaman "micarpeta" sin embargo no son la misma. Por lo tanto como haces para diferenciarlas? veo dos opciones de momento. Pasar en orden jerarquico hasta micarpeta, con lo que ya tendrias el historial de como llego ahi, o bien, que directamente escriba el "path", con lo que descomponiendo el path ya puedes generar el arbol.

Que es lo que no estoy viendo??

un saludo
  #6 (permalink)  
Antiguo 12/07/2004, 15:17
Avatar de sism82  
Fecha de Ingreso: octubre-2003
Ubicación: Guadalajara
Mensajes: 865
Antigüedad: 20 años, 6 meses
Puntos: 1
por otro lado el link de cluster propone una solucion mas acertada creo
  #7 (permalink)  
Antiguo 12/07/2004, 15:43
Avatar de zarate  
Fecha de Ingreso: septiembre-2001
Ubicación: Madrid
Mensajes: 164
Antigüedad: 22 años, 7 meses
Puntos: 0
Cita:
Iniciado por sism82
a ver.... entonces como accedes a las carpetas internas sin acceder directa o indirectamente a las carpetas padre?
Pues porque en la tabla de las carpetas hay un campo que es id_parent. Si ese campo no es = 0, quiere decir que está dentro de otra, a través de ese id_parent se puede recorrer el arbol "al revés".

Conseguirlo ya lo he conseguido... a la forma bestia, es decir, hacer una consulta dentro de un while hasta que id_parent = 0. Este método me parece un poco bestia.

Me voy a leer el enlace de Cluster que tiene muy buena pinta y ya os cuento algo.

Gracias!
__________________
Zárate
  #8 (permalink)  
Antiguo 14/07/2004, 14:55
Avatar de zarate  
Fecha de Ingreso: septiembre-2001
Ubicación: Madrid
Mensajes: 164
Antigüedad: 22 años, 7 meses
Puntos: 0
Bueno, llevo 2 días dándole vueltas al método "avanzado" que se propone en el enlace que dejó Cluster y la verdad es que estoy alucinado.

Estoy intentanto averiguar cómo seleccionar sólo los primeros hijos de un nodo. No sé si se podría modificar la función display_tree para que sólo hiciera un paso del bucle (que no creo y no evitaría que se seleccionasen, sino que sólo no se mostrasen) o se puede hacer directamente a través de una consulta.

¿Alguien tiene un poco de experiencia con esto? Seguiré investigando.

Gracias!
__________________
Zárate
  #9 (permalink)  
Antiguo 14/07/2004, 15:16
Avatar de zarate  
Fecha de Ingreso: septiembre-2001
Ubicación: Madrid
Mensajes: 164
Antigüedad: 22 años, 7 meses
Puntos: 0
La única relación que encuentro entre los hijos de un mismo nodo, es que el valor de la derecha del hijo de la izquierda es el anterior al valor de la izquierda del siguiente hijo de la derecha.... ya, yo lo he tenido que leer un par de veces para asegurarme que lo ponía bien : ) Pero que en el gráfico se ve muy fácil

De todas formas, ¿cómo se plasma eso en una consulta?

¬_¬
__________________
Zárate
  #10 (permalink)  
Antiguo 14/07/2004, 15:43
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 22 años, 3 meses
Puntos: 129
Tal vez alguna de estas classes ya hechas (con el tema resuelto sobre los "nodos" y ver "ramas") te ayuden ...

http://www.phpclasses.org/search.htm...h=1&internal=1

Un saludo,
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 21:33.