[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: