Pagina 5 di 22 primaprima ... 3 4 5 6 7 15 ... ultimoultimo
Visualizzazione dei risultati da 41 a 50 su 217
  1. #41
    Penso di aver sbagliato a trascrivere, il codice dovrebbe essere questo:
    codice:
    d.add(0,-1,'Categoria Principale','insert_under.php?id=1');
    d.add(1,0,'Abbigliamento','insert_under.php?id=2');
    d.add(2,1,'Giacche','insert_under.php?id=4');
    d.add(3,0,'Calzature','insert_under.php?id=3');
    d.add(4,3,'Scarpe','insert_under.php?id=5');
    d.add(5,4,'Da Ginnastica','insert_under.php?id=6');
    d.add(6,5,'Nike 707','scheda.php?id=1','','','img/page.gif');
    dove ho i collegamenti ad una pagina "scheda.php" che mi mostra i contenuti dell'id 1 della tabella prodotti e una pagina "insert_under.php" che mi inserisce (tramite la funzione ns_insert_node() contenuta in essa) una categoria sotto l'id della categoria padre.
    What is the |\/|atrix?

  2. #42
    Ci ho pensato e ripensato e sono arrivato a questa conclusione:
    Le tabelle "relazioni" e "prodotti" vanno bene per come sono, ma la tabella "categorie" dovrebbe essere così composta:
    codice:
    ------------------------------------------------
    id |       nome           | sx | dx | prodotti |
    ------------------------------------------------
     1 | Categoria Principale |  1 | 12 |     0    |
     2 | Abbigliamento        |  2 |  5 |     0    |
     3 | Calzature            |  6 | 11 |     0    |
     4 | Giacche              |  3 |  4 |     0    |
     5 | Scarpe               |  7 | 10 |     0    |
     6 | Da Ginnastica        |  8 |  9 |     1    |
    ------------------------------------------------
    La colonna prodotti non fa altro che indicarmi se ci sono prodotti sotto quella categoria (in questo caso lancio una seconda query nel ciclo che mi mette in lista il campo "nome_prod" della tabella "prodotti").
    Il codice che dovrei stampare è questo:
    codice:
    d.add(1,-1,'Categoria Principale','insert_under.php?id=1');
    d.add(2,1,'Abbigliamento','insert_under.php?id=2');
    d.add(4,2,'Giacche','insert_under.php?id=4');
    d.add(3,1,'Calzature','insert_under.php?id=3');
    d.add(5,3,'Scarpe','insert_under.php?id=5');
    d.add(6,5,'Da Ginnastica','insert_under.php?id=6');
    d.add(10000001,6,'Nike 707','scheda.php?id=1','','','img/page.gif');
    Che è così generato...
    1)Di default è così composto:
    codice:
    d.add(ID-CATEGORIA,ID-CATEGORIA-NELLA-QUALE-E'-CONTENUTA,'NOME-CATEGORIA','insert_under.php?id=ID-CATEGORIA');
    2)Nel caso sia una categoria principale il secondo campo deve essere -1
    codice:
    d.add(ID-CATEGORIA,-1,'NOME-CATEGORIA','insert_under.php?id=ID-CATEGORIA');
    2)Nel caso sia un prodotto (cioè se nella colonna "prodotti" c'è il valore settato ad 1) il codice dovrebbe essere:
    codice:
    d.add(1000000+ID-PRODOTTO,ID-CATEGORIA-NEL-QUALE-E'-CONTENUTO,'NOME-PRODOTTO','scheda.php?id=ID-PRODOTTO','','','img/page.gif');
    Aggiungo 1000000 all'id del prodotto poichè nel codice non ci possono essere due id con valore uguale (in questo caso sono il prodotto "Nike 707" e la "Categoria Principale" che hanno tutti e due id=1) perciò ipotizzo che il numero max di categorie che posso raggiungere è 10.000.000 e gli aggiungo l'id cosi il nuovo id per javascript del prodotto è 10000001,10000002 ecc..

    Spero di non aver detto cavolate... ma non riesco a trovare un metodo migliore!
    Ora l'unico problema che non so come risolvere è: Come faccio a sapere l'id della categoria nella quale è contenuta ogni categoria?
    Cioè nell'esempio di giacche (che ha l'id 4) come faccio a calcolarmi l'id della categoria Abbigliamento (cioè id 2) che la contiene?
    Vi ringrazio ancora per l'attenzione!
    What is the |\/|atrix?

  3. #43
    Utente di HTML.it L'avatar di M4rko
    Registrato dal
    Dec 2000
    Messaggi
    619
    [supersaibal]Originariamente inviato da |\/|atrix
    Ora l'unico problema che non so come risolvere è: Come faccio a sapere l'id della categoria nella quale è contenuta ogni categoria?
    Cioè nell'esempio di giacche (che ha l'id 4) come faccio a calcolarmi l'id della categoria Abbigliamento (cioè id 2) che la contiene?
    Vi ringrazio ancora per l'attenzione! [/supersaibal]
    Mi son perso un paio di post, scusate

    Per rispondere a quest'ultima domanda, ti faccio notare che il problema ricade sempre nella questione della ricerca del percorso dalla radice ad un nodo, anche se in effetti qua non ti serve il percorso completo, ma solo un determinato nodo (quello che nell'albero sta sopra al nodo figlio).

    Per farla breve, una query che funziona:
    codice:
    SELECT id FROM tabella WHERE sx < $sx_figlio AND dx > $dx_figlio ORDER BY sx DESC LIMIT 1;
    usando < e > invece di <= e >= si elimina in sostanza il nodo figlio dai risultati. Poichè chi sta sopra nell'albero ha il valore sx inferiore, ti basta ordinare per questo valore decrescente (ORDER BY sx DESC) e visto che dell'elenco di risultati ottenuti ti interessa solo il primo elemento, ecco spiegato quel LIMIT 1.
    Tutti hanno bisogno di credere in qualcosa.
    Io credo che mi farò un'altra birra.


  4. #44
    [supersaibal]Originariamente inviato da M4rko
    Per farla breve, una query che funziona:
    codice:
    SELECT id FROM tabella WHERE sx < $sx_figlio AND dx > $dx_figlio ORDER BY sx DESC LIMIT 1;
    [/supersaibal]
    Ho provato a fare questa query ma il risultato è l'id stesso del record... non quello in cui è contenuto!
    What is the |\/|atrix?

  5. #45
    Utente di HTML.it L'avatar di M4rko
    Registrato dal
    Dec 2000
    Messaggi
    619
    Attenzione ad usare < e > invece di <= e >=

    Naturalmente i valori $sx_figlio e $dx_figlio li hai prelevati da una select precedente:
    codice:
    SELECT sx, dx FROM tabella WHERE id=$id
    dove $id è l'elemento di cui vuoi trovare il padre
    Tutti hanno bisogno di credere in qualcosa.
    Io credo che mi farò un'altra birra.


  6. #46
    Grazie mille! Ha funzionato! Ho fatto così:
    Codice PHP:
    function display_tree_form($root) {
       global 
    $tabella;
       
    $sql "SELECT sx, dx FROM $tabella WHERE id={$root}";
       
    $result mysql_query($sql) or die(mysql_error());
       
    $row mysql_fetch_array($result);

       
    $right = array();

       
    $sql "SELECT id, nome, FROM $tabella WHERE sx BETWEEN {$row['sx']} AND {$row['dx']} ORDER BY sx ASC";
       
    $result mysql_query($sql) or die(mysql_error());

       while (
    $row mysql_fetch_array($result)) {
           if (
    count($right)>0) {
               while (
    $right[count($right)-1]<$row['dx']) {
                   
    array_pop($right);
               }
           }

           
    $sql2 "SELECT sx, dx FROM $tabella WHERE id='".$row['id']."'";
           
    $result2 mysql_query($sql2) or die (mysql_error());
           
    $row2 mysql_fetch_array($result2);
           
    $sql3 "SELECT id FROM $tabella WHERE sx < {$row2['sx']} AND dx > {$row2['dx']} ORDER BY sx DESC LIMIT 1";
           
    $result3 mysql_query($sql3) or die (mysql_error());
           
    $row3 mysql_fetch_array($result3);

           if(
    $row3['id'] == ""){
           
    $row3['id'] = "-1";
           }
           echo 
    str_repeat('-',count($right))." Id: ".$row['id']." Nome: ".$row['nome']." Sotto: ".$row3['id']."
    "
    ;

           
    $right[] = $row['dx'];
       }

    Ma ora avrei una piccola domandina... Facendo così non mi aumentano il numero di query? Il bello di questo sistema era che le query erano poche giusto?
    What is the |\/|atrix?

  7. #47
    zalve

    interessato al Modified Preorder Tree Traversal Algorithm ma abbastanza inesperto in databases, mi sono messo giu' a fare un po' di prove ...

    cosa volevo fare
    trovare il modo di slegare completamente questa tipologia dal tipo di tabella, ovvero un' unica e snella tabella tree ( albero ) senza vincoli su campi di alcun tipo, solo l' auto_increment , sx e dx


    cosa ne e' venuto fuori
    queste sono le 3 tabelle rappresntanti cio' che volevo fare, una tree, una ramo ( slegata ) ed un' altra foglie ( slegata anch' essa )

    codice:
    struttura utilizzabile in MySQL come in SQLite ( ad eccezione dell' AUTO_INCREMENT )
    
    CREATE TABLE tree (
    	id INTEGER UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    	sx INTEGER UNSIGNED NOT NULL,
    	dx INTEGER UNSIGNED NOT NULL
    );
    
    CREATE TABLE branch (
    	id INTEGER UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    	tree_id INTEGER UNSIGNED NOT NULL,
    	name VARCHAR(255) NOT NULL 
    );
    
    CREATE TABLE leaf (
    	id INTEGER UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    	branch_id INTEGER UNSIGNED NOT NULL,
    	content TEXT
    );
    ... e questi sono gli inserts, che per ora non prendono affato in considerazione la tabella foglia ma vorrebbero simulare la stessa cosa dell' articolo, soffermandosi quindi sui rami ...
    codice:
    inserts utilizzabili in MySQL come in SQLite
    
    INSERT INTO tree VALUES( NULL, 1, 14  );
    INSERT INTO tree VALUES( NULL, 2, 13  );
    INSERT INTO tree VALUES( NULL, 3, 4  );
    INSERT INTO tree VALUES( NULL, 5, 6  );
    INSERT INTO tree VALUES( NULL, 7, 12  );
    INSERT INTO tree VALUES( NULL, 8, 9  );
    INSERT INTO tree VALUES( NULL, 10, 11  );
    INSERT INTO branch VALUES( NULL, 1, 'Massimiliano'  );
    INSERT INTO branch VALUES( NULL, 2, 'Francesco' );
    INSERT INTO branch VALUES( NULL, 3, 'Mario' );
    INSERT INTO branch VALUES( NULL, 4, 'Luigi' );
    INSERT INTO branch VALUES( NULL, 5, 'Fabio' );
    INSERT INTO branch VALUES( NULL, 6, 'Piero' );
    INSERT INTO branch VALUES( NULL, 7, 'Gianni' );

    Ecco come risolvere con un' unica query ( 1 con 2 sotto query ) il percorso fino a Piero , come nell' esempio di questo articolo
    ( testata su MySQL 4.1 ed SQLITE 2.8 )
    codice:
    SELECT branch.name 
    FROM branch 
    LEFT JOIN tree 
    ON tree.id = branch.tree_id 
    WHERE tree.sx <= 
    ( SELECT tree.sx FROM tree, branch WHERE tree.id = branch.tree_id AND branch.id = 6 ) 
    AND tree.dx >= 
    ( SELECT tree.dx FROM tree, branch WHERE tree.id = branch.tree_id AND branch.id = 6 );
    Ecco come risolvere con 2 query ( solo 2, niente sottoquery ) lo stesso percorso
    ( testata su MySQL 4.1 ed SQLITE 2.8 )
    codice:
    SELECT tree.sx AS sx, tree.dx AS dx FROM tree, branch WHERE tree.id = branch.tree_id AND branch.id = 6
    SELECT branch.name FROM branch LEFT JOIN tree ON tree.id = branch.tree_id WHERE tree.sx <= $sx AND tree.dx >= $dx

    ed in fine ecco come contare i sotto livelli di un ramo, in questo caso quello dell' articolo, il 2
    ( testata su MySQL 4.1 ed SQLITE 2.8 )
    codice:
    SELECT ROUND( ( tree.dx - tree.sx - 1 ) / 2 , 0 ) FROM tree, branch WHERE tree.id = branch.tree_id AND branch.id = 2;

    In fine l' idea e' quella di prendere le foglie in base all' id del branch, cosi' da non esagerare con le join e fare al massimo ed in totale 3 query per gerarchie piu' o meno complesse ...




    mi dite cosa ne pensate ?
    secondo voi e' in questo modo piu' semplice gestire anche le modifiche ? ( cambio id del tree al branch e fine dei problemi )
    suggerimenti ?
    grazie



    [editato]
    in alternativa alle join ci sono anche queste 2 query con WHERE, dai tests su phpmyadmins piu' veloci ...

    SELECT branch.name FROM branch, tree WHERE branch.tree_id = tree.id AND tree.sx <=
    ( SELECT tree.sx FROM tree, branch WHERE tree.id = branch.tree_id AND branch.id = 6 )
    AND tree.dx >=
    ( SELECT tree.dx FROM tree, branch WHERE tree.id = branch.tree_id AND branch.id = 6 );


    SELECT branch.name FROM branch, tree WHERE branch.tree_id = tree.id AND tree.sx <= sx AND tree.dx >= dx
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  8. #48
    le domande qui sopra restano valide, comunque sia ho fatto un "giochino"


    questo file, se richiamato in una cartella si connette al database tree_menu.db ( utenti linux, createlo e metetelo a chmod 777 o quello che e' ) , installa un' esempio simile a quello di questo articolo, vi permette di giocare con i rami, se clickate sul [+] vi chiede con che nome inserire in db, se clickate sul nome, rimuove quel ramo ... e' non troppo stabile pero' magari serve a qualcuno che sta' smanettando con questo approccio alla gerarchia su database ... si basa su SQLITE, quindi per PHP5 , fatemi sapere



    codice:
    
    // CONNESSIONE AL DATABASE
    $db = sqlite_open( 'tree_menu.db' );
    
    // CONTROLLI E GESTIONE INSERIMENTI
    if( isSet( $_GET['add'], $_GET['name'] ) ) {
    	$_GET['add'] = (int)$_GET['add'];
    	$_GET['name'] = sqlite_escape_string( $_GET['name'] );
    	$q1 = sqlite_unbuffered_query(
    		$db,
    		"SELECT
    			*
    		FROM
    			tree
    		ORDER BY
    			sx
    		ASC"
    	);
    	$row = 0;
    	$q2 = "BEGIN;
    	";
    	while( $r = sqlite_fetch_array( $q1, SQLITE_NUM ) ) {
    		$r[2] = (int)$r[2];
    		if( (int)$r[1] <= $_GET['add'] ) {
    			$q2 .= "UPDATE tree SET dx = ".( $r[2] + 2 )." WHERE id = {$r[0]};
    			";
    		}
    		else {
    			$q2 .= "UPDATE tree SET sx = ".( (int)$r[1] + 2 ).", dx = ".( $r[2] + 2 )." WHERE id = {$r[0]};
    			";
    		}
    		$row = &$r[0];
    	}
    	$q2 .= "INSERT INTO tree VALUES ( NULL, ".( ++$_GET['add'] ).", ".( ++$_GET['add'] )." );
    	INSERT INTO branch VALUES ( NULL, ( SELECT MAX(id) FROM tree ), '{$_GET['name']}' );
    	COMMIT;";
    	sqlite_unbuffered_query( $db, $q2 );
    }
    // CONTROLLI E GESTIONE ELIMINAZIONI
    elseif( isSet( $_GET['remove'] ) ) {
    	$_GET['remove'] = (int)$_GET['remove'];
    	$q1 = sqlite_query(
    		$db,
    		"SELECT branch.tree_id, tree.sx FROM branch, tree WHERE branch.tree_id = tree.id AND branch.id = ".$_GET['remove']
    	);
    	if( sqlite_num_rows( $q1 ) === 1 ) {
    		$tree_id = $tree_sx = 0;
    		while( $r = sqlite_fetch_array( $q1, SQLITE_NUM ) ) {
    			$tree_id = $r[0];
    			$tree_sx = (int)$r[1];
    		}
    		sqlite_unbuffered_query( $db, "DELETE FROM tree WHERE id = ".$tree_id );
                    $q1 = sqlite_unbuffered_query(
    			$db,
    			"SELECT
    				*
    			FROM
    				tree
    			ORDER BY
    				sx
    			ASC"
    		);
    		$row = 0;
    		$q2 = "BEGIN;
    		";
    		while( $r = sqlite_fetch_array( $q1, SQLITE_NUM ) ) {
    			$r[2] = (int)$r[2];
    			if( (int)$r[1] < $tree_sx ) {
    				$q2 .= "UPDATE tree SET dx = ".( $r[2] - 2 )." WHERE id = {$r[0]};
    				";
    			}
    			else {
    				$q2 .= "UPDATE tree SET sx = ".( (int)$r[1] - 2 ).", dx = ".( $r[2] - 2 )." WHERE id = {$r[0]};
    				";
    			}
    			$row = &$r[0];
    		}
    		$q2 .= "DELETE FROM branch WHERE id = {$_GET['remove']};
    		COMMIT;";
    		sqlite_unbuffered_query( $db, $q2 );	
    	}
    }
    
    // PRENDO TUTTO L' ALBERO
    $q1 = @sqlite_query(
    	$db,
    	"SELECT
    		branch.id, branch.name, tree.sx
    	FROM
    		branch, tree
    	WHERE
    		branch.tree_id = tree.id
    	ORDER BY
    		tree.sx
    	ASC"
    );
    // SE C'E' LO MOSTRO
    if( $q1 && sqlite_num_rows( $q1 ) > 0 ) {
    	$redirect = false;
    	$output = "
    	<script type=\"text/JavaScript\">
    		function add( where ) {
    			var w = window.prompt( 'Insert the name of the new branch' );
    			var str = '{$_SERVER['PHP_SELF']}?add=' + where + '&name=' + w.split(\"'\").join(\"\\\'\");
    			window.open( str, '_self' );
    		}
    	</script>
    	<pre>";
    	$last_sx = 1;
    	$tab = 0;
    	while( $r = sqlite_fetch_array( $q1, SQLITE_NUM ) ) {
    		$compare = (int)$r[2];
    		if( $compare === ( $last_sx + 1 ) ) {
    			$tab++;
    		}
    		elseif( $compare > ( $last_sx + 2 ) && $tab >= ( $compare - ( $last_sx + 2 ) ) ) {
    			$tab -= $compare - ( $last_sx + 2 );
    		}
    		$output .= str_repeat( "\t", $tab )."- ";
    		$output .= "<a title=\"remove this branch\" href=\"{$_SERVER['PHP_SELF']}?remove={$r[0]}\">{$r[1]}</a>";
    		$output .= "[<a title=\"add in this branch\" href=\"#\" onclick=\"add( {$r[2]} ); return false;\">+</a>]\r";
    		$last_sx = $compare;
    	}
    	echo $output."</pre>";
    }
    // ALTRIMENTI CREO IL DATABASE
    else {
    	$redirect = true;
    	sqlite_unbuffered_query(
    		$db,
    		"BEGIN;
    		CREATE TABLE tree (
    			id INTEGER UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    			sx INTEGER UNSIGNED NOT NULL,
    			dx INTEGER UNSIGNED NOT NULL
    		);
    		CREATE TABLE branch (
    			id INTEGER UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    			tree_id INTEGER UNSIGNED NOT NULL,
    			name VARCHAR(255) NOT NULL 
    		);
    		CREATE TABLE leaf (
    			id INTEGER UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    			branch_id INTEGER UNSIGNED NOT NULL,
    			content TEXT
    		);
    		INSERT INTO tree VALUES( NULL, 1, 16  );
    		INSERT INTO tree VALUES( NULL, 2, 15  );
    		INSERT INTO tree VALUES( NULL, 3, 6  );
    		INSERT INTO tree VALUES( NULL, 4, 5  );
    		INSERT INTO tree VALUES( NULL, 7, 8  );
    		INSERT INTO tree VALUES( NULL, 9, 14  );
    		INSERT INTO tree VALUES( NULL, 10, 11  );
    		INSERT INTO tree VALUES( NULL, 12, 13  );
    		INSERT INTO branch VALUES( NULL, 1, 'Massimiliano'  );
    		INSERT INTO branch VALUES( NULL, 2, 'Francesco' );
    		INSERT INTO branch VALUES( NULL, 3, 'Mario' );
    		INSERT INTO branch VALUES( NULL, 4, 'Luigi' );
    		INSERT INTO branch VALUES( NULL, 5, 'Fabio' );
    		INSERT INTO branch VALUES( NULL, 6, 'Piero' );
    		INSERT INTO branch VALUES( NULL, 7, 'Gianni' );
    		INSERT INTO branch VALUES( NULL, 8, 'Luca' );
    		COMMIT;"
    	);
    }
    // CHIUDO LA CONNESSIONE
    sqlite_close( $db );
    
    // VERIFICO SE HO CREATO O MENO IL DATABASE
    if( $redirect === true ) {
    	// IN CASO RICARICO LA PAGINA
    	header('Location:'.$_SERVER['PHP_SELF']);
    }
    
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  9. #49
    ciao andr3a, non mi è chiaro il motivo per cui hai ritenuto necessario scomporre la struttura in 3 tabelle separate rispetto a una sola (non sto dicendo che non c'è, dico che non l'ho capito io ).

    Quali sarebbero i vantaggi?

  10. #50
    Utente di HTML.it L'avatar di M4rko
    Registrato dal
    Dec 2000
    Messaggi
    619
    [supersaibal]Originariamente inviato da andr3a
    zalve [/supersaibal]
    ciao

    mi dite cosa ne pensate ?
    secondo voi e' in questo modo piu' semplice gestire anche le modifiche ? ( cambio id del tree al branch e fine dei problemi )
    suggerimenti ?
    grazie
    Bhe è un argomento su cui si può ragionare.

    Mi sfugge l'utilità della terza tabella, in che modo andrebbe usata?
    Penso che due tabelle siano più che sufficienti, in quanto con una gestisci i dati legati agli elementi che stai trattando (nel caso dell'articolo, tutte le informazioni sugli impiegati) mentre nell'altra gestisci le informazioni sulla gerarchia, per cui la tabella "tree" per come l'hai impostata è già completa, mentre la tabella "branch" va estesa a seconda delle esigenze. "Estesa" nel senso di aggiungere tutti i campi che ti servono, l'esempio dell'articolo era abbastanza minimale.
    Questa idea di dividere il tutto in due tabella ha l'utilità, come giustamente dicevi, di slegare questo modo di vedere la struttura gerarchica dal tipo di tabella, o meglio, di slegare la rappresentazione della gerarchia dalle informazioni aggiuntive che non riguardano la gerarchia stessa. E' quindi un vantaggio piu che altro concettuale, cioè memorizzare informazioni diverse (e probabilmente slegate) in posti diversi.

    Sui vantaggi pratici ho dei dubbi. Non credo che sia più semplice gestire le modifiche, e cambiare l'id del tree nella tabella branch non mi sembra necessario, in quanto le informazioni sulla gerarchia stanno in tree, non in branch. Se ho interpretato male quello che proponi, prova a fare qualche esempio in piu cosi ci capiamo meglio ma secondo me le modifiche alla struttura verranno gestite in maniera pressoche identica al modello con una tabella unica.

    Eventuali svantaggi cosi a prima vista non ne vedo, se non il fatto di introdurre un'ulteriore complicazione in un metodo che già di suo non è troppo immediato. Complicazione che poi si traduce nel dover fare un join, quindi forse troppo complicata non è

    Piu tardi provo a ragionarci con piu attenzione
    Tutti hanno bisogno di credere in qualcosa.
    Io credo che mi farò un'altra birra.


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.