Foros del Web » Programando para Internet » PHP »

PseudoAporte : encontrar paths entre tablas

Estas en el tema de PseudoAporte : encontrar paths entre tablas en el foro de PHP en Foros del Web. Para un sistema en el que estoy trabajando, he construido esta función, que, usada creativamente, puede que os sea útil. A partir de una definición ...
  #1 (permalink)  
Antiguo 20/02/2013, 05:55
Avatar de dashtrash
Colaborador
 
Fecha de Ingreso: abril-2007
Ubicación: Ni en Sevilla,ni en Sanlúcar..qué más da..
Mensajes: 927
Antigüedad: 17 años, 7 meses
Puntos: 270
PseudoAporte : encontrar paths entre tablas

Para un sistema en el que estoy trabajando, he construido esta función, que, usada creativamente, puede que os sea útil.
A partir de una definición de qué tablas hay en el sistema, cuáles son sus primary key (sólo 1 campo por primary key es soportado), y cuáles son sus relaciones con otras tablas, intenta construir el path mínimo que conecta las tablas entre sí, y devuelve una query (inner join) por cada permutación de tablas:
Código PHP:
Ver original
  1. function initializeSample()
  2. {
  3.     $keys=array("A"=>"a0","B"=>"b0","C"=>"c0","D"=>"d0","E"=>"e0","F"=>"f0","Q"=>"q0","P"=>"p0","H"=>"h0");
  4.     $nodes=array(
  5.             "A"=>array("a1"=>"B", "a2"=>"H"),
  6.             "B"=>array("b1"=>"D", "b2"=>"C"),
  7.             "C"=>array("c1"=>"E", "c2"=>"F"),
  8.             "D"=>array(),
  9.             "E"=>array("e1"=>"H"),
  10.             "F"=>array("f1"=>"E"),
  11.             "Q"=>array("q1"=>"A"),
  12.             "P"=>array("p1"=>"Q"),
  13.             "H"=>array()
  14.             );
  15.     $objects=array_keys($nodes);
  16.     return array("objects"=>$objects,"relations"=>$nodes,"keys"=>$keys);        
  17. }
  18. function buildDistances($objects,$relations,$oKeys)
  19. {
  20.     $curDistance=0;
  21.     while(1)
  22.     {
  23.        
  24.         $cont=0;
  25.        
  26.         for($k=0;$k<count($objects);$k++)
  27.         {
  28.             $curObject=$objects[$k];
  29.                
  30.             if($curDistance==0)
  31.             {
  32.                 foreach($relations[$curObject] as $key=>$value)
  33.                 {
  34.                     $distances[$curObject][$value]=1;
  35.                     $paths[$curObject][$value]="/".$value."[$key]";
  36.                     $queries[$curObject][$value]=$curObject." INNER JOIN $value ON ".$curObject.".$key=$value.".$oKeys[$value];
  37.                     $distances[$value][$curObject]=1;
  38.  
  39.                     $paths[$value][$curObject]="/".$curObject."|$key|";
  40.                     $queries[$value][$curObject]=$value." INNER JOIN $curObject ON ".$curObject.".$key=$value.".$oKeys[$value];
  41.                    
  42.                 }
  43.                 $cont=1;
  44.                 continue;
  45.             }
  46.             $adist=& $distances[$curObject];
  47.            
  48.             foreach($adist as $bName=>$bdist)
  49.             {                
  50.                
  51.                 if($bdist==$curDistance)
  52.                 {
  53.                     foreach($distances[$bName] as $cName=>$cDist)
  54.                     {                        
  55.                         if($cName == $curObject)
  56.                             continue;
  57.                         $fullDist=$cDist+$curDistance;
  58.                         if(!$adist[$cName] || ($adist[$cName] > $fullDist))
  59.                         {
  60.                             $cont++;
  61.                             $adist[$cName]=$fullDist;
  62.                             $paths[$curObject][$cName]=$paths[$curObject][$bName].$paths[$bName][$cName];
  63.                             $queries[$curObject][$cName]=$queries[$curObject][$bName]." ".substr($queries[$bName][$cName],strpos($queries[$bName][$cName]," ")+1);
  64.                         }
  65.                     }
  66.                 }
  67.             }
  68.  
  69.         }
  70.         $curDistance++;
  71.          if($cont == 0)
  72.             break;
  73.     }
  74.     foreach($queries as $o1=>$val)
  75.     {
  76.         foreach($val as $o2=>$text)
  77.             $queries[$o1][$o2]="SELECT ".$o1.".*,".$o2.".* FROM ".$text;
  78.     }
  79.     return array($distances,$paths,$queries);
  80. }
  81. $r = initializeSample();
  82. var_dump(buildDistances($r["objects"],$r["relations"],$r["keys"]));

Ejecutando esta funcion, se retorna, en el tercer elemento del array:

Código PHP:
Ver original
  1. 'A' =>
  2.         array
  3.           'B' => string 'SELECT A.*,B.* FROM A INNER JOIN B ON A.a1=B.b0',
  4.           'H' => string 'SELECT A.*,H.* FROM A INNER JOIN H ON A.a2=H.h0',
  5.           'Q' => string 'SELECT A.*,Q.* FROM A INNER JOIN Q ON Q.q1=A.a0',
  6.           'D' => string 'SELECT A.*,D.* FROM A INNER JOIN B ON A.a1=B.b0 INNER JOIN D ON B.b1=D.d0',
  7.           'C' => string 'SELECT A.*,C.* FROM A INNER JOIN B ON A.a1=B.b0 INNER JOIN C ON B.b2=C.c0',
  8.           'E' => string 'SELECT A.*,E.* FROM A INNER JOIN H ON A.a2=H.h0 INNER JOIN E ON E.e1=H.h0',
  9.           'P' => string 'SELECT A.*,P.* FROM A INNER JOIN Q ON Q.q1=A.a0 INNER JOIN P ON P.p1=Q.q0',
  10.           'F' => string 'SELECT A.*,F.* FROM A INNER JOIN B ON A.a1=B.b0 INNER JOIN C ON B.b2=C.c0 INNER JOIN F ON C.c2=F.f0'
  11.       'B' =>
  12.         array
  13.           'A' => string 'SELECT B.*,A.* FROM B INNER JOIN A ON A.a1=B.b0',
  14.           'D' => string 'SELECT B.*,D.* FROM B INNER JOIN D ON B.b1=D.d0',
  15.           'C' => string 'SELECT B.*,C.* FROM B INNER JOIN C ON B.b2=C.c0',
  16.           'H' => string 'SELECT B.*,H.* FROM B INNER JOIN A ON A.a1=B.b0 INNER JOIN H ON A.a2=H.h0',
  17.           'Q' => string 'SELECT B.*,Q.* FROM B INNER JOIN A ON A.a1=B.b0 INNER JOIN Q ON Q.q1=A.a0',
  18.           'E' => string 'SELECT B.*,E.* FROM B INNER JOIN C ON B.b2=C.c0 INNER JOIN E ON C.c1=E.e0',
  19.           'P' => string 'SELECT B.*,P.* FROM B INNER JOIN A ON A.a1=B.b0 INNER JOIN Q ON Q.q1=A.a0 INNER JOIN P ON P.p1=Q.q0',
  20.           'F' => string 'SELECT B.*,F.* FROM B INNER JOIN C ON B.b2=C.c0 INNER JOIN F ON C.c2=F.f0',
  21.      .....
  #2 (permalink)  
Antiguo 20/02/2013, 10:42
Avatar de pateketrueke
Modernizr
 
Fecha de Ingreso: abril-2008
Ubicación: Mexihco-Tenochtitlan
Mensajes: 26.399
Antigüedad: 16 años, 7 meses
Puntos: 2534
Respuesta: PseudoAporte : encontrar paths entre tablas

¿Un caso de uso?

Porque se ve bueno y todo, pero aún no me imagino un caso real donde lo podría necesitar.
__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.
  #3 (permalink)  
Antiguo 20/02/2013, 11:03
Avatar de dashtrash
Colaborador
 
Fecha de Ingreso: abril-2007
Ubicación: Ni en Sevilla,ni en Sanlúcar..qué más da..
Mensajes: 927
Antigüedad: 17 años, 7 meses
Puntos: 270
Respuesta: PseudoAporte : encontrar paths entre tablas

Este trozo de código no está pensado para ir en ningún sistema final.
Tal cual está, sirve para ejecutarlo, y obtener unas queries base, con unos joins ya hechos, e irlas perfilando poco a poco, sin estar pensando en los nombres de los campos para los joins.
Lógicamente, esas queries iniciales autogeneradas son muy toscas, pero la idea es tener una "materia prima" sobre la que ir trabajando.
Pero en lo que estoy trabajando, un sistema de generación de código, donde hay mucha más información disponible (no sólo las tablas y las relaciones), las queries se pueden hacer algo más "inteligentemente".
Además, en la siguiente función (en la que estoy trabajando ahora), se le especifica una query concreta indicando qué tablas van a ser la salida, qué campos de qué tablas deben ser fijos, y qué campos de qué tablas van a ser parámetros.
Esto se edita visualmente en un plugin del Mysql Workbench, en la vista del modelo de datos.
A partir de estas queries, se generan automáticamente listados html / ajax.
Tanto la query, como los listados, etc, son toscos.Sirven para tener una base hecha, y libre de errores, sobre la que se sigue construyendo.

Como dices, encontrarle un caso de uso para un sistema final, es complicado.Pero cada vez uso más código cuyo destino es el scaffolding del sistema final, y de ahi sale esta función

Etiquetas: mysql
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

SíEste tema le ha gustado a 1 personas




La zona horaria es GMT -6. Ahora son las 14:56.