Pagina 1 di 11 1 2 3 ... ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 103
  1. #1

    tabelle e ricorsività in mysql

    Per la prima volta mi sto accingendo a fare una tabella che poi richiederà delle operazioni diciamo ricorsive per risalire al nodo padre. Cerco di spiegarmi meglio. devo inserire in questa tabella una struttura del tipo categoria -> sottocategoria -> sottocategoria2 -> etc etc etc solo che non so per quanti livelli. Inoltre è possibile che per arrivare dal nodo padre alla foglia [che non avrà altri nodi figli] a volte ci siano 5passaggi, a volte solo 2 etc. Insomma, avrete capito che non posso creare un numero fisso di tabelle per ogni livello, e così ho pensato di implementare una struttura del genere, e volevo un vostro parere e/o un vostro consiglio su qualcosa di meglio e più veloce da implementare, e che magari richieda anche meno tempo quando dovrò andare a reperire i miei dati.
    Io ho fatto due tabelle; una per le foglie, che rappresenteranno l'ultima catena della famiglia, che naturalmente conterrà un campo [chiave esterna] in cui ci sarà il valore dell'ultimo id_padre ad essa collegato. E poi ho fatto un'unica tabella per tutte le categorie così strutturata:

    codice:
    +--------------+---------------+---------------+
    | id_categoria |   categoria   | id_nodo_padre |
    +--------------+---------------+---------------+
    |      1       |     Sport     |       0       |
    +--------------+---------------+---------------+
    |      2       |  Individuali  |       1       |
    +--------------+---------------+---------------+
    |      3       |   Di squadra  |       1       |
    +--------------+---------------+---------------+
    |      4       |     Calcio    |       3       |
    +--------------+---------------+---------------+
    |      5       |     Serie A   |       4       |
    +--------------+---------------+---------------+
    |      6       |      Sci      |       2       |
    +--------------+---------------+---------------+
    |      7       |     Hobby     |       0       |
    +--------------+---------------+---------------+
    |      8       |    Leggere    |       7       |
    +--------------+---------------+---------------+
    Avrete certamente notato che dove compare lo 0 è perché quel nodo è padre. L'unica cosa che so di per certo è che i livelli non saranno mai più di 5; almeno così mi hanno detto. Ma mi hanno anche detto che i record da inserire nella tabella saranno parecchi, si parla di qualche migliaio.

    Volevo sapere, una struttura così, può andare?è troppo pesante da supportare?richiedera query chilometriche per riuscire a costruire la struttura di un nodo?chilometriche forse no, perché la struttura sarà ricorsiva, ma richiederà un utilizzo di memoria eccessivo?richiederà un tempo improponibile ricostruire l'intero ramo?

    Scusate tutte queste domande, ma vorrei avere un'opinione da parte di chi ha già utilizzato strutture del genere e che sappia darmi qualche dritta prima di perdermi in un qualcosa di troppo grande ed oneroso.

    Ringrazio tutti fin da ora!
    Talvolta anche una persona apparentemente inutile si rivela un abile samurai dalla forza di mille uomini, dimostrando di poter rinunciare alla vita e che il suo cuore si è completamente identificato con quello del suo padrone

  2. #2
    Se vuoi ti faccio un esempio di query ricorsiva, ma secondo me spreca troppa memoria.
    In pratica esegue una query per ogni dato estratto.
    Ad esempio nel tuo caso ci vorranno minimo 8 query.

    Stavo sviluppando qualcosa anche io, ma tutto con una sola query:
    http://forum.html.it/forum/showthrea...hreadid=744847
    L'unico problema è che mi sono bloccato nel ciclo.

  3. #3
    Grazie per la risposta!
    Io a dire il vero per ricorsività intendevo che eseguisse una sola query diverse volte, non una sola volta una query complicatissima, perché pensavo fosse meno dispendioso eseguire magari una query 4volte. A parte il fatto che una queryricorsiva non la saprei fare, se mi fai un esempio ti ringrazio molto!

    Talvolta anche una persona apparentemente inutile si rivela un abile samurai dalla forza di mille uomini, dimostrando di poter rinunciare alla vita e che il suo cuore si è completamente identificato con quello del suo padrone

  4. #4

  5. #5
    Ti ringrazio per il link!
    Allora è come pensavo io, la query non è ricorsiva. La query è messa all'interno di una funzione che richiama sè stessa, e la medesima query, con parametri diversi, viene eseguita ad ogni 'ciclo'.

    Penso quindi che la strada che ho intrapreso vada bene. E penso che non sapendo a priori quanti saranno i livelli sia anche l'unica strada che si possa prendere. Aspetto comunque smentite

    Talvolta anche una persona apparentemente inutile si rivela un abile samurai dalla forza di mille uomini, dimostrando di poter rinunciare alla vita e che il suo cuore si è completamente identificato con quello del suo padrone

  6. #6
    a me non sembra il metodo ottimale ... secondo me sono necessarie 2 tabelle, 1 contenente tutte le sottotabelle presenti, per fare una query ed avere la possibilita' di strutturare una sola query per avere tutti i risultati .. l' altra unica per avere tutte le cartelle o categorie e sotto categorie ... adesso faccio un po' di prove poi posto l' esempio
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  7. #7
    Non ho ben capito il discorso di avere una tabella che contenga tutte le sottotabelle presenti, forse perché non ho capito cosa intendi per sottotabelle, ma aspetterò con ansia l'esempio

    Io ero partito dall'idea di fare due tabelle distinte una per le foglie e una che contenga, diciamo, la struttura gerarchica, perché fra le foglie e le semplici categorie c'è un pò di differenza. In attesa ti posto la struttura delle mie tabelle, se hai voglia di darci un'occhiata e di dirmi cosa ne pensi è tutto ben accetto.

    codice:
    #
    # Struttura della tabella `categorie`
    #
    
    CREATE TABLE categorie (
      id_categoria int(11) NOT NULL auto_increment,
      nome_categoria varchar(255) NOT NULL default '',
      nodo_padre int(11) NOT NULL default '0',
      PRIMARY KEY  (id_categoria)
    ) TYPE=MyISAM;
    
    #
    # Struttura della tabella `foglie`
    #
    
    CREATE TABLE foglie (
      id_foglia int(11) NOT NULL auto_increment,
      id_categoria int(11) NOT NULL default '0',
      id_paese smallint(6) NOT NULL default '0',
      titolo varchar(255) NOT NULL default '',
      descrizione text NOT NULL,
      data date NOT NULL default '0000-00-00',
      PRIMARY KEY  (id_foglia)
    ) TYPE=MyISAM;
    Ti ringrazio!
    Talvolta anche una persona apparentemente inutile si rivela un abile samurai dalla forza di mille uomini, dimostrando di poter rinunciare alla vita e che il suo cuore si è completamente identificato con quello del suo padrone

  8. #8
    fatto ... allora, la cosa importante e' usare, nella seconda query, il mysql_num_row perche' se le sottocategorie hanno tutte lo stesso nome per il campo, il mysql_fetch_assoc prende il solo campo per riferimento ... comunque adesso ti posto il codice da me usato:

    nome database per la prova:
    prove

    dump del database
    codice:
    -- --------------------------------------------------------
    
    -- 
    -- Table structure for table `categories`
    -- 
    
    CREATE TABLE `categories` (
      `id` int(10) NOT NULL auto_increment,
      `category` varchar(100) default NULL,
      PRIMARY KEY  (`id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
    
    -- 
    -- Dumping data for table `categories`
    -- 
    
    INSERT INTO `categories` (`id`, `category`) VALUES (1, 'category_0'),
    (2, 'category_1'),
    (3, 'category_2'),
    (4, 'category_3');
    
    -- --------------------------------------------------------
    
    -- 
    -- Table structure for table `category_0`
    -- 
    
    CREATE TABLE `category_0` (
      `id` int(10) NOT NULL auto_increment,
      `category` varchar(100) default NULL,
      `parent_id` int(10) NOT NULL default '0',
      PRIMARY KEY  (`id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
    
    -- 
    -- Dumping data for table `category_0`
    -- 
    
    INSERT INTO `category_0` (`id`, `category`, `parent_id`) VALUES (1, 'Food', 0),
    (2, 'Games', 0);
    
    -- --------------------------------------------------------
    
    -- 
    -- Table structure for table `category_1`
    -- 
    
    CREATE TABLE `category_1` (
      `id` int(10) NOT NULL auto_increment,
      `category` varchar(100) default NULL,
      `parent_id` int(10) NOT NULL default '0',
      PRIMARY KEY  (`id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
    
    -- 
    -- Dumping data for table `category_1`
    -- 
    
    INSERT INTO `category_1` (`id`, `category`, `parent_id`) VALUES (1, 'Fruit', 1),
    (2, 'Meat', 1),
    (3, 'Pac Man', 2);
    
    -- --------------------------------------------------------
    
    -- 
    -- Table structure for table `category_2`
    -- 
    
    CREATE TABLE `category_2` (
      `id` int(10) NOT NULL auto_increment,
      `category` varchar(100) default NULL,
      `parent_id` int(10) NOT NULL default '0',
      PRIMARY KEY  (`id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
    
    -- 
    -- Dumping data for table `category_2`
    -- 
    
    INSERT INTO `category_2` (`id`, `category`, `parent_id`) VALUES (1, 'Red', 1),
    (2, 'Yellow', 1),
    (3, 'Breef', 2),
    (4, 'Pork', 2);
    
    -- --------------------------------------------------------
    
    -- 
    -- Table structure for table `category_3`
    -- 
    
    CREATE TABLE `category_3` (
      `id` int(10) NOT NULL auto_increment,
      `category` varchar(100) default NULL,
      `parent_id` int(10) NOT NULL default '0',
      PRIMARY KEY  (`id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
    
    -- 
    -- Dumping data for table `category_3`
    -- 
    
    INSERT INTO `category_3` (`id`, `category`, `parent_id`) VALUES (1, 'Cherry', 1),
    (2, 'Banana', 2);


    codice di prova
    codice:
    mysql_connect( 'localhost', 'root', '' );
    mysql_select_db( 'prove' );
    $query = &mysql_unbuffered_query( 'SELECT category FROM categories' );
    while( $r = &mysql_fetch_row( $query ) ) {
    	if( isSet( $newquery ) == false ) {
    		$newquery = 'SELECT * FROM '.$r[0].'';
    		$oldr = &$r[0];
    	}
    	else {
    		$newquery .= ' LEFT JOIN '.$r[0].' ON '.$oldr.'.id = '.$r[0].'.parent_id';
    		$oldr = &$r[0];
    	}
    }
    // qui se vuoi fare una prova in phpMyAdmin ti rendi subito
    // conto che hai tutta la gerarchia gia' strutturata ...
    // echo $newquery; // poi la usi in phpMyAdmin
    
    
    $TableMapping = 3; // IMPORTANTE
    // questa variabile e' fondamentale perche' tramite
    // phpMyAdmin o altri devi vedere , in base alle tue tabelle
    // ogni quanto esiste quella chiamata categoria, perche' sono tute uguali ( devono esserlo ) ... in questo caso ogni 3 
    // colonne c'e' la corrispettiva per categoria
    
    
    $StartMapping = 1; // IMPORTANTE
    // questa invece indica qual'e' la prima colonna contenente le informazioni per categoria
    
    $queryTree = Array();
    $globalKeys = '';
    $query = &mysql_unbuffered_query( $newquery );
    while( $r = &mysql_fetch_row( $query ) ) {
    
    	$a = $StartMapping;
    	$arrayKeys = '$queryTree';
    	while( isSet( $r[$a] ) ) {
    	        $arrayKeys .= '[\\''.$r[$a].'\\']';
    		$a+= $TableMapping;
    	}
    	$globalKeys .= $arrayKeys.' = Array();';
    }
    eval( $globalKeys );
    echo '<pre>';
    var_dump( $queryTree );
    echo '</pre>';
    2 query di cui una irrisoria ( quella per i nomi delle sotto tabelle ) ed una sola query per tutti i risultati che vuoi .

    In questo caso ho solo creato la gerarchia, ma aggiungendo poche riche puoi crearti anche valori interni per ogni ramo della gerarchia ...


    Per la dinamicita' ti basta aggiungere altre tabelle in database e scrivere il loro nome ( in ordine di gerarchia ) sulla tabella categories .


    fammi sapere
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  9. #9
    posto anche il risultato
    codice:
    array(2) {
      ["Food"]=>
      array(2) {
        ["Fruit"]=>
        array(2) {
          ["Red"]=>
          array(1) {
            ["Cherry"]=>
            array(0) {
            }
          }
          ["Yellow"]=>
          array(1) {
            ["Banana"]=>
            array(0) {
            }
          }
        }
        ["Meat"]=>
        array(2) {
          ["Breef"]=>
          array(0) {
          }
          ["Pork"]=>
          array(0) {
          }
        }
      }
      ["Games"]=>
      array(1) {
        ["Pac Man"]=>
        array(0) {
        }
      }
    }
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  10. #10
    1 tabella per ogni categoria?
    Lo trovo un po' scomodo come metodo e soprattutto invasivo.


    Vabbè, de gustibus

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.