Gerarchia per albero

di il
7 risposte

Gerarchia per albero

Ciao a tutti
Sto costruendo il mio db per gestire il mio albero genealogico.
A questo punto sto tentando di visualizzare il classico albero che in sostanza è come un diagramma di flusso che si espande da un individuo a salire per generazioni esponenzialmente (1 individuo, 2 genitori, 4 nonni, 8 bisnonni, 16 trisvaoli ecc...)
il mio db è basato su 2 tabelle: TBLGdxlate (che è una tabella collegata al db che viene generata da un sito online e che non posso modificare) e tabella NOTE in cui ho aggiunto campi che a me servono e che non esistono nella prima.
In base a queste due tabelle ho creato una query da poter utilizzare poi per la composizione dell'albero.

Tale Query che ho chiamato "Query_PERSONA" (semplifico un po') contiene campi dalla prima tabella TBLGdxlate:
ID dell'individuo (INDI_ID)
Il nome composto da cognome e nome: (Fullname)
Un campo (Father_ID) che lo correla come padre di un altro individuo INDI_ID
Un campo (Mother_ID) che lo correla come madre di un altro individuo INDI_ID
Un campo (FAM_C) che correla tutti gli appartenenti ad un nucleo famigliare (fratelli e sorelle dell'individuo)
Altri campi dalla tabella NOTE che qui tralascio per l'esposizione del problema.

A questo punto per poter generare l'albero a "piramide" ho creato una seconda Query "Query COMPONI ALBERO" che, NON HO TROVATO ALTRO MODO - e ritengo che non sia il sistema corretto - ed è quello che mi manca, concatena la stessa query "Query PERSONA" duplicata varie volte in cascata, cioè:

(Faccio l'esempio per la query che compone la generazione dell'individuo con i 2 genitori ed i 2 genitori con i 4 nonni):

Nella Query COMPONI ALBERO inserisco:
Query PERSONA
La aggiungo altre 6 volte (2 per i genitori, 4 per i nonni) e mi ritrovo in totale
Query PERSONA, (individuo)
Query PERSONA 1, Query PERSONA 2, (genitori)
Query PERSONA 3, Query PERSONA 4, Query PERSONA 5, Query PERSONA 6 (nonni)

A questo punto faccio un join a salire:
JOIN INDIVIDUO > Genitori
Query Persona.Father_ID > join Query Persona1.INDI_ID
Query Persona.Mother_ID > join Query Persona2.INDI_ID

JOIN Genitori > Nonni
Query Persona1.Father_ID > join Query Persona3.INDI_ID
Query Persona1.Mother_ID > join Query Persona4.INDI_ID
Query Persona2.Father_ID > join Query Persona5.INDI_ID
Query Persona2.Mother_ID > join Query Persona6.INDI_ID

I campi destinazioni della Query COMPONI ALBERO sono tutti i vari fullname (Query PERSONA_Fullname, Query Persona1_Fullname ecc...)

E il sistema - seppure "BARBARO" - funziona...

O meglio: funziona fino ai bisnonni quando la concatenazione deve utilizzare 15 query (1+2+4+8).
Se aggiungo la generazione successiva (trisnonni) devo aggiungere altre 16 query e concatenarle e diventano in totale 31 query (1+2+4+8+16) e diventa una query stra-lenta ovviamente (e immagino concettualmente sbagliata).

In sostanza: come posso giungere alla composizione dell'albero in un modo che sia corretto e veloce partendo dalla mia Query PERSONA?

Scusate se sono poco sintetico ma ho cercato di illustrare la situazione intricata che ho creato maldestramente

Grazie in anticipo, ciao
J

7 Risposte

  • Re: Gerarchia per albero

    Jfk105 ha scritto:


    il mio db è basato su 2 tabelle: TBLGdxlate (che è una tabella collegata al db che viene generata da un sito online e che non posso modificare) e tabella NOTE in cui ho aggiunto campi che a me servono e che non esistono nella prima.
    tabelle di cui però non conosciamo nulla e forse sta tutto lì.
    Non ho guardato bene il resto del post, ho visto che usi 15 query... eh no, non va bene.
    Qui trovi un esempio di "gerarchia infinita". Il contenuto è banale: ricette. La struttura e il codice invece sono preziosissimi:
    Cerca anche dell'altro, sempre fatto da @Alex, lì.
    Poi per la "rappresentazione grafica" è tutta un'altra faccenda e ho visto che l'argomento l'hai già proposto sul forum e non a caso sono stato zitto.
  • Re: Gerarchia per albero

    La gestione gerarchica si realizza con 2 sole tabelle una delle quali viene usata in SELF_Reference proprioper definire la gerarchia.
    TblAnagrafica(1)<--->(m)tblRelazione(m)<--->(1)tblAnagrafjca_1
    La tabella in self reference è sempre la tabella anagrsfica che viene scandita proprio per assegnare ad ogni anagrafica il rapporto relazionale.
    Ovviamente nella tabella Relazioni andrai a definire jl rapporto parenrale.

    Questi sistema tuttavia impone una sufficiente dimestichezza con la logica ricorsiva da gestire con codice.
    Il modo di rappresentare questi casi è usando il treeview.
    Di certo non con query come pensavi in quanto è una logica alveoli finiti, mentre il tuo caso non ha livelli di profondità definiti ne finiti.

    Poi serve ragionare sulla stampa dell'albero... ed è molto complessa in quanto deve sviluppare la gerarchia per livello.

    Personalmente temo che se non hai buona dimestichezza con codice OOP non riuscirai a fare molto, soprattutto a livello di report che va proprio disegnato.
  • Re: Gerarchia per albero

    Guarda ti incollo un intervento che ho fatto in altri lidi sempre relativo alla gestione gerarchica con qualche esempio specifico.

    Se vogliamo affrontare la questione della gestione Gerarchica, serve individuare bene da subito l'esigenza.
    Ci sono 2 linee da considerare che si scelgono in base alla profondità richiesta o necessaria.
    1) Profondità 1, ovvero 1 Prodotto può avere solo 1 Padre, questo è banale e si ottempera con una Relazione 1-M, ma se questa è l'esigenza l'argomento è già chiuso in quanto banale e non starei nemmeno a considerarlo.

    2) Profondità (n) ovvero non definita e volutamente non definibile, quindi da 1÷n, in questo caso ci sarebbero 2 sottoelementi da considerare, ma io preferisco usare sempre quello più flessibile.
    Qui parliamo di vera gestione gerarchica ad albero, in cui ogni elemento può avere più figli ma anche che ogni elemento può avere più padri.
    In questo caso per la gestione si usano 2 Tabelle fisiche, ma, nella realtà una Tabella viene usata in SELF_REFERENCE... in modo da consentire la gestione ricorsiva a livelli non definiti.

    Faccio un esempio culinario, che risulta banale solo per chi non capisce di cosa si parla...
    Se vogliamo gestire delle ricette di cucina, dobbiamo comprendere che servono 3 Elementi concettuali:
    1) Prodotto: Materie Prime(queste per definizione non avranno mai figli, ma solo padri, ed in questa osservazione sta il concetto di TIPO)
    Prezzemolo, Mele, Farina, Acqua ecc...
    2) Prodotto: Materie Semilavorate (queste per definizione possono avere sia figli, che padri)
    Crema Zabaione, Pasta Frolla, Budino... (queste materie essendo a loro volta costituite da ricette, avranno N figli ma magari uno di essi è a sua volta un Semilavorato)
    3) Prodotto: Materia Finale (queste per definizione hanno SOLO figli e nessun genitore)
    Torta di Mele (sarà fatta da Pasta Frolla, il semilavorato di prima e... Mele ecc...)

    Per realizzare questa struttura(semplifico per la comprensione):
    tblProdotti
    IdProdotto
    Tipo (1=Finito;2=Semilavorato;3=Primo)
    Nome
    Prezzo

    tblRicetta(questa è la tabella che costituisce i rapporti gerarchici, in questo caso culinario è la Ricetta)
    IdProdotto
    IdParent
    Qtà
    UM

    Nella rappresentazione ER si disegneranno le tabelle in questo modo:
    tblProdotti(1)<--->(m)tblRicetta(m)<--->(1) tblProdotti_1

    Quella che ho indicato come [tblProdotti_1] è appunto l'utilizzo in SELF_REFERENCE della Tabella prodotti, e consente che ogni elemento possa essere flessibilmente gerarchico.

    La distinzione che ho fatto inizialmente, sui 3 tipi è fondamentale quando si realizza l’interfaccia grafica, in quanto si dovrà consentire di selezionare come Ingredienti della Ricetta solo Prodotti con Tipo>1

    Ovviamente questo ragionamento banalizzato sulle ricette è solo per facilitarne la comprensione, ma è applicabile a qualsiasi gestione gerarchica Multilivello, produzione di componentistica elettrica/meccanica per la realizzazione di prodotti finiti o parziali.

    La difficoltà sta poi nella gestione dell’interfaccia grafica, che va da se che trova la massima chiarezza nell’utilizzo del TreeView in linea concettuale, ma in realtà è solo una questione di organizzazione.

    Ci sono poi 2 aspetti da non sottovalutare:
    1) Ricavare la DI.BA del prodotto, e di conseguenza il costo complessivo splittato per singolo ITEM con totali parziali e totali generali dello stesso.
    2) Stampare l’esploso della DI.BA, i REPORT

    Per il primo serve appunto come ti ha indicato anche BSF, usando come DB JET creare una funzione ricorsiva in VBA che partendo dall’Articolo scala la profondità gerarchica e calcola il costo... la funzione da scrivere è banale in se ma non così tanto, diciamo che non è a prova di stupido, e se sei abituato a non dichiarare le Variabili usate e la profondità aumenta, il sistema va in Overflow sicuramente...

    Ci sono invece RDBMS che supportano funzioni SQL ricorsive... ed in questo caso la gestione cambia dovendo delegare il Server, e sicuramente cambiano, in meglio, anche le prestazioni.

    Quì trovi qualche indicazione:
    https://it.qaz.wiki/wiki/Hierarchical_and_recursive_queries_in_SQL

    Per il secondo punto invece serve conoscere bene la gestione dei Report.
    Mentre per gerarchie ad 1 Livello, ripeto è banale e si gestisce con un Raggruppamento, quando NON si conosce a priori la profondità della Gerarchia, o meglio quando non si è posto un LIMITE stretto alla gerarchia, perché non si sa a prescindere il livello di profondità da rappresentare... questo modo ri gestire l'ambiente non funziona.
    In questo caso serve ribaltare i concetti e slegarsi dalla Gerarchia, sfruttando una Tabella dedicata, che consente di SERIALIZZARE i dati da gerarchici a sequenziali come fosse una tabella di Excel, includendo il Livello di profondità gerarchica ed i dati necessari ai ricalcoli.
    Il report pertanto diventa semplice da gestire come un banale report MONOLIVELLO, in cui eventualmente si può gestire l’aspetto grafico dell’indentazione sapendo il LIVELLO ed usando Caratteri a spaziatura fissa.

    Saluti
    @Alex
  • Re: Gerarchia per albero

    Philcattivocarattere ha scritto:


    ...
    Qui trovi un esempio di "gerarchia infinita". Il contenuto è banale: ricette. La struttura e il codice invece sono preziosissimi:
    Cerca anche dell'altro, sempre fatto da @Alex, lì.

    @Alex ha scritto:


    Faccio un esempio culinario, che risulta banale solo per chi non capisce di cosa si parla...
    Lo sapevo che gira gira si arrivava lì.
  • Re: Gerarchia per albero

    Ma si è semplice da comprendere senza fare troppa teoria...
  • Re: Gerarchia per albero

    Vi ringrazio per le informazioni, onestamente non ho capito quasi nulla poichè non sono un programmatore ma un appassionato di genealogia.. mi sa che sto tentando una cosa troppo complessa per me.
    Cmq ho provato a scaricare il demo del RIcettario e per conoscenza (se servisse ad altri utenti) quando si scarica (da Chrome) viene visto come pagina asp non zip (ho rinominato l'estensione e ovviamente così si vede il contenuto).

    Ritornando al mio problema io parto da una tabella UNICA (lasciamo stare la seconda dove ho alcuni riferimenti che potrei non considerare, per semplificare) in cui ho :
    INDIVIDUO con ID e un ID_FATHER ed un ID_MOTHER
    ad esempio: Paperino Junior è figlio di Paperino e Paperina e a sua volat Paperino è figlio di Paperino Senior

    ID 1 Paperino Junior , ID FATHER 2 ID MOTHER 3 (ID FATHER 2 corrisponde all'ID 2 di Paperino, ID MOTHER 3 corrisponde all'ID 3 di Paperina
    ID 2 Paperino, ID FATHER 4 ID MOTHER 5
    ID 3 Paperina, ID FATHER 6, ID MOTHER 7
    ID 4 Paperino Senior, ID FATHER 8, ID MOTHER 9... ecc

    Ovviamente io so che 4 (Paperino Senior) è nonno di 1 (Paperino Junior) ma la tabella "sa" solo che è padre di 2 (Paperino)
    Questa struttura la eredito e non la posso modificare
    Per cui la struttura sarà

    1
    /\
    2 3
    / \ / \
    4 5 6 7

    Quindi avrò sempre e solo ID, Father ID e Mother ID per tutti gli individui in UN'UNICA tabella
    E cioè ID 1 ha ID 2 come padre e quindi il FATHER ID di 1 corrisponde all'ID 2 ma ID 2 (padre) ha a sua volta il FATHER ID che corrisponde all' ID 4...
    e questo si ripete ovviamente anche per le madri e per tutti gli individui in tabella a salire.

    Potrei utilizzare il metodo self reference?

    So di essere ignorante in materia per cui se non è possibile mi fermo qui, non voglio abusare della vostra conoscenza nè pazienza
    Grazie
    Ciao
    J
  • Re: Gerarchia per albero

    Forse ho capito e trovato il modo e sembra funzionare...
    Al posto delle Query ho duplicato la tabella principale tot volte, assegnato gli alias alle tabelle e inserito le destinazioni dalle tabelle.
    Ora devo solo con pazienza inserire le generazioni ma già vedo una generazione in più.
    Ho trovato qui lo spunto dopo il vostro aiuto: http://www.databasedev.co.uk/self-join_query.htm
    Grazie, ciao
    J
Devi accedere o registrarti per scrivere nel forum
7 risposte