[genropy] Re: Tabelle gerarchiche.

  • From: Giovanni Porcari <giovanni.porcari@xxxxxxxxx>
  • To: genropy@xxxxxxxxxxxxx
  • Date: Mon, 15 Feb 2016 08:09:34 +0100


Il giorno 14 feb 2016, alle ore 21:29, Gollum1 <gollum1.smeagol1@xxxxxxxxx> 
ha scritto:

Non ho ancora finito di spulciare la documentazione, ma come ben sa Giovanni, 
mi interessano particolarmente le tabelle gerarchiche, e quando avrò finito 
di studiare questa parte, spero di riuscire a fare una documentazione 
adeguata.

Ho capito la dichiarazione, e l'idea di base, in pratica una tabella 
gerarchica è la componente del db che di avvicina di più ad un file xml, e di 
conseguenza ad una bag (o meglio, è la perfetta rappresentazione di una bag 
con un path come chiave, che si riflette poi in una struttura simile ad un 
file xml). Non ho ancora esplorato come viene poi trasformato a livello sql e 
quindi nel db vero e proprio, ma lo farò prossimamente.

Una tabella gerarchica non è altro che una normale tabella con la differenza 
che vengono aggiunte alcune colonne di sistema.
La prima colonna che viene aggiunta è 'parent_id'. Tutti i record con parent_id 
== NULL sono record radice.
Vengono poi create le colonne  'hierarchical_pkey' e '_parent_h_pkey' che 
salvano rispettivamente la concatenazione
delle pkey al proprio livello e al livello precedente. Le pkey sono separate da 
'/'.
Per ogni colonna definita poi nell'attributo 'hierarchical' vengono poi create 
le rispettive colonne attuale e parent.
Quindi se ad esempio hai messo hierarchical = 'description,code', ti troverai:

'hierarchical_description' e '_parent_h_description'
'hierarchical_code' e '_parent_h_code'

Vengono inoltre aggiunte 2 formule column:
'child_count' che dice quanti figli ha il record e 'hlevel' che dice il livello 
gerarchico del record (0==radice)

Inoltre vengono creati tutti i trigger necessari a mantenere allineati i campi 
al variare del parent_id.
Se quindi ad esempio hai un record che ha un parent_id e lo 'trascini' in un 
altro record, il parent_id
verrà cambiato a quello del record dove hai droppato. Poi i trigger faranno in 
modo di riallineare
tutti i campi gerarchici in modo trasparente.


Quello che non mi è ancora del tutto chiaro, è come faccio a caratterizzare i 
vari livelli del path gerarchico…


Una tabella gerarchica si propone, come suggerisce il termine di gestire 
gerarchie.
Ora, nel mondo reale, le gerarchie possono essere omogenee o disomogenee.

Una gerarchia omogenea è ad esempio: 'nonno', 'padre','figlio', 'nipote'.
Ogni entità è come quella del livello superiore e ha le stesse colonne.
Inoltre ogni nodo della gerarchia è 'reale' e quindi potrebbe essere gestito
nel database. Vedremo fra un momento perchè lo definisco 'reale'.


Prendiamo poi una struttura di magazzino di un'azienda che produce medicinali.

Potrebbe avere al primo livello: 
'materie_prime','semilavorati','prodotti_finiti','materiali_confezionamento'.

Poi al secondo livello di 'materie_prime' potrebbe avere 
'principi_attivi','eccipienti','coloranti' 
E via dicendo.

Da questo deduciamo che in questo tipo di gerarchia solo le 'FOGLIE' sono 
'reali' mentre ogni altro
nodo è solo un raggruppamento. 

Per questo tipo di gerarchie la soluzione ottimale è quella di usare una 
tabella gerarchica e una tabella
piatta. La tabella gerarchica contiene SOLO i RAGGRUPPAMENTI mentre i record 
'reali' vanno nella tabella piatta.

I record reali (prodotto) sono gli unici ad avere delle colonne significative 
oltre ad un nome (descrizione) ed eventuale codice.

I record di tabella gerarchica (in questo caso sarebbe chiamata 
'tipo_prodotto') potrebbero avere oltre a nome (descrizione) ed eventuale codice
anche dei campi specifici da considerare una sorta di default per l'intero ramo.
Ad esempio nel nostro campo potrebbero alcuni gruppi avere il campo 
'pericoloso'. Ma è un uso che raramente si fa e quindi
in questo tipo di strutture si usano solo le colonne viste.


Per quello che riguarda le colonne della tabella piatta che relazioniamo, se, 
come spesso accade, parliamo di entità abbastanza disomogenee,
potremo mettere tutte le colonne comuni (ad esempio in questi caso potremmo 
avere 'unità_misura','fornitore_id','prezzo','tipo_iva'
'scorta_minima' ecc..) mentre poi avremmo il problema di come gestire le 
colonne che sono significative solo per uno specifico ramo.

Esistono due soluzioni: la prima e di definirle 'tutte' e quindi nel nostro 
caso potremmo avere 'formula_chimica' che vale per
i prodotti chimici e 'presentazione' ('compresse','bustine','fiale') che vale 
per un prodotto finito.
I campi possono essere numerosissimi e quindi otterremmo un insieme di colonne 
che cpntiene tutti i campi possibili e immaginabili.
Ovviamente dovremo poi gestire opportunamente la form di imputazione per 
mostrare/nascondere le colonne opportune in funzione 
del tipo.

La modalità che preferiamo noi è quella dei dynamic_fields. 
Per utilizzarli (magari in altra sede darò una descrizione completa) in pratica 
si definisce
per ogni ramo della struttura gerarchica un insieme di campi che 
caratterizzeranno i record
fisici di quel livello.
Da notare che l'insieme di campi definiti 'eredita' quelli dei livelli 
precedenti.
Quindi, ad esempio, nella categoria 'prodotti_chimici' potrei definire 
'formula' e nella sottocategoria
'coloranti' mettere 'colore'.
Un record di colorante avrà quindi sia una 'formula' che un 'colore'.
Nei record primari i dynamic fields vengono salvati in una colonna bag.

Esiste poi un  component che genera in modo automatico i pezzi di form 
necessari all'inputazione
dei valori dinamici e alla presentazione in tabelle o stampe.

Questa è la 'teoria'… In pratica devi vedere il tuo problema e capire la 
soluzione migliore.


Prendiamo la struttura che stavo elaborando settimana scorsa:

Stato/sede/plesso/palazzo/corpo/piano/stanza

Non ho ben capito se per caratterizzare i diversi livelli, devo giocare con i 
sysfield nel model, identificarlo attraverso la struttura rappresentativa in 
una risorsa th_ o, come mi pare di aver inteso, posso usare una tabella di 
appoggio che in qualche modo gestisca le sue caratteristiche.

Nel tuo caso hai una struttura 'disomogenea' di entità 'reali'.

Quindi se ti bastano poche informazioni collegate puoi mettere le colonne in 
più e nasconderle se non servono
(ad esempio le colonne 'indirizzo' e numero_piani servono al palazzo e non 
certo alla stanza) oppure,
come avevamo iniziato a fare insieme definisci una tabella 'tipo' che contiene 
i campi dinamici e li potrai
allora definire livello per livello con il vantaggio di poter in qualunque 
momento aggungere dei campi
senza mettere mano al codice.



Altra cosa, con questa gestione, posso anche sopprimere qualche livello, ove 
non necessario? Per esempio, nella sede di Milano usiamo la suddivisione dei 
palazzi in corpi, ma a mecenate, per esempio, non è così... posso quindi in 
qualche modo collassare il path? (Se le metto manualmente è sicuramente 
possibile, visto che ogni path vive solo per se stesso e non ha nulla a che 
fare con gli altri, ma quando è gestito attraverso la tabella di appoggio o 
le altre tecniche, è ancora fattibile la cosa?

La tabella gerarchica è per sua natura flessibile è quindi NON esiste una 
struttura rigida. Quindi è molto adatta
a gestire entità che si trovano nel mondo reale senza la necessità di 
complicarsi troppo la vita
con numerosissime tabelle specializzate.

Quali parti della vecchia documentazione posso andarmi a studiare? Ci sono 
una serie di termini particolari che devo/posso ricercare, per poi cercare di 
armonizzare il tutto in una spiegazione unica?


Se questi aspetti la documentazione è solo il codice e gli esempi. Per il resto 
potete affidarvi a queste
mail e alla buona volontà mia o di altri di procedere nella documentazione.


Ciao

G

Other related posts: