Nelle lezioni precedenti, sono stati introdotti molti concetti sul funzionamento di OrientDB, che potremo utilizzare per la realizzazione di un database "a documenti". Ne progetteremo uno che impieghi gli strumenti visti sinora, facendo attenzione a:
- definire le classi occorrenti con eventuali campi
LINK
eEMBEDDED
, ove necessario; - mettere in relazione i record;
- impiegare SQL per le operazioni di base, e
TRAVERSE
per navigare le relazioni.
Il progetto che realizzeremo mira a costruire un database aziendale in cui vengono registrati i dati personali dei dipendenti tenendo nota delle loro capacità informatiche (immaginiamo si tratti di programmatori) e del livello di studio posseduto, nonchè dei progetti cui hanno preso parte:
- la classe Dipendente conterrà i dati fondamentali (nome e cognome), oltre a un oggetto embedded contenente gli skill posseduti dal programmatore con relativa valutazione, espressa con numeri interi da 0 a 10;
- un'altra classe rappresenta il livello di studio posseduto: per semplicità, ci interesserà memorizzare solo se il dipendente è diplomato o laureato. Nei record di classe Dipendente aggiungeremo, oltre a quanto detto al punto precedente, un campo apposito che lo collegherà ad un oggetto indicante il livello di studio raggiunto;
- la classe Progetto possiederà una proprietà indicante il nome ed un collegamento ad una lista di dipendenti che vi hanno preso parte. Renderemo quest'ultima relazione reciproca fornendo la classe
Dipendente
di un ulteriore campo che lo collegherà ai progetti in cui è stato coinvolto, realizzando una relazione molti-a-molti.
Classi e record
La prima classe che definiamo è quella rappresentante il livello di studio dei dipendenti:
CREATE CLASS LivelloStudio
CREATE PROPERTY LivelloStudio.livello STRING
Vi inseriremo all'interno un paio di record:
INSERT INTO LivelloStudio SET livello='Laurea'
INSERT INTO LivelloStudio SET livello='Diploma'
Si può vedere il contenuto della classe con il comando:
SELECT FROM LivelloStudio
I RID che otterremo dalla schermata saranno usati per stabilire collegamenti:
# |@RID |@CLASS |livello
----+-----+-------------+-------
0 |#11:0|LivelloStudio|Laurea
1 |#11:1|LivelloStudio|Diploma
----+-----+-------------+-------
La classe Dipendente
sarà invece definita nel modo seguente:
CREATE CLASS Dipendente
CREATE PROPERTY Dipendente.nome STRING
CREATE PROPERTY Dipendente.cognome STRING
CREATE PROPERTY Dipendente.livelloStudio LINK LivelloStudio
CREATE PROPERTY Dipendente.capacita EMBEDDED
CREATE PROPERTY Dipendente.progetti LINKSET
INSERT INTO Dipendente SET nome='Paolo', cognome='Rossi',livelloStudio=#11:0, capacita={"Java":10,"PHP":7}
INSERT INTO Dipendente SET nome='Giulio', cognome='Bianchi',livelloStudio=#11:1, capacita={"Java":6,"PHP":8}
INSERT INTO Dipendente SET nome='Enzo', cognome='Verdi',livelloStudio=#11:0, capacita={"Java":7,"PHP":7}
INSERT INTO Dipendente SET nome='Fulvio', cognome='Neri',livelloStudio=#11:0, capacita={"Java":5,"PHP":8}
Gli id assegnati dal sistema ai nuovi record saranno, rispettivamente, #12:0, #12:1, #12:2 e #12:3. Osservando la struttura della classe, notiamo come questa sia un nodo centrale del nostro piccolo database, ed infatti essa include già
riferimenti alle altre classi. Ove è necessario un collegamento ai record LivelloStudio abbiamo usato un LINK
, specificando anche il tipo di record destinazione: il sistema controllerà così in automatico la validità dei dati inseriti.
Per la relazione con i progetti, è stato usato un LINKSET
, che non ammette duplicati: ciò non è un problema
per noi in quanto il progetto verrà menzionato una sola volta in riferimento ad un dipendente.
La classe Progetto servirà per lo più a stabilire un collegamento con i dipendenti:
CREATE CLASS Progetto
CREATE PROPERTY Progetto.nome STRING
CREATE PROPERTY Progetto.partecipanti LINKSET
INSERT INTO Progetto SET nome='GestioneBiblioteca'
INSERT INTO Progetto SET nome='CalcoloTasse'
Navigare le relazioni
I nuovi record di classe Progetto riceveranno gli id #13:0 e #13:1. E' arrivato quindi il momento di
stabilire i collegamenti tra i progetti e i dipendenti, ci avvarremo in questo caso di un'attitudine particolare
del comando UPDATE studiato appositamente per strutture dati:
UPDATE #13:0 ADD partecipanti=[#12:0, #12:1]
UPDATE #13:1 ADD partecipanti=[#12:0, #12:2, #12:3]
UPDATE #12:0 ADD progetti=[#13:0, #13:1]
UPDATE #12:1 ADD progetti=#13:0
UPDATE #12:2 ADD progetti=#13:1
UPDATE #12:3 ADD progetti=#13:1
Dove abbiamo previsto un collegamento a più record sono state usate le parentesi quadre []
per definire un
array di collegamenti.
A questo punto si potrebbero manipolare le classi create con normali operazioni CRUD, ma quello che ci interessa
ora è sperimentare meglio l'uso del comando TRAVERSE
. Per iniziare ad intuirne le potenzialità è sufficiente
provare nel nostro database il comando SELECT FROM Dipendente
e TRAVERSE * FROM Dipendente
.
Il primo elencherebbe i quattro record della classe Dipendente, mentre il secondo mostrerebbe otto record: i quattro relativi ai dipendenti, i due dei livelli di studio ed i due dei progetti. Questo perchè TRAVERSE
segue i collegamenti che trova, e quindi pubblicherà anche i dati relativi ai recod collegati ai dipendenti, ognuno citato una sola volta.
Utilizzando il comando TRAVERSE livelloStudio FROM Dipendente
chiederemmo a TRAVERSE
di pubblicare
tutti i record Dipendente sviluppando solo i collegamenti presenti nel campo livelloStudio
. In questo caso, quindi, l'output mostrerebbe 6 record: quattro dipendenti più i due livelli di studio cui complessivamente sono collegati.
Un aspetto interessante (che non possiamo verificare sul nostro esempio) è che se il campo su cui viene sviluppato il collegamento
fosse presente anche nei record secondari, l'esplorazione sarebbe proseguita ulteriormente, scendendo di livello.
La navigazione tramite TRAVERSE
può iniziare da un singolo record. Ad esempio, il comando seguente:
TRAVERSE * from #13:0
inizia la navigazione dei record a partire dal #13:0, che nel database di prova è di tipo Progetto. TRAVERSE
sviluppa quindi in modalità molto più efficiente le finalità assolte dai JOIN nel mondo relazionale e può anche costituire la fonte
da cui un SELECT
potrebbe partire per una migliore esposizione dei dati. Se volessimo, ad esempio, contare quanti
diplomati e laureati hanno preso parte al progetto con RID #13:0, potremmo utilizzare la seguente query:
SELECT livelloStudio.livello,count(livelloStudio) FROM
(TRAVERSE partecipanti FROM #13:0)
GROUP BY livelloStudio
dove l'elenco dei partecipanti ottenuto con TRAVERSE
verrebbe raggruppato in base al livello di studio, e sull'esito
di tale raggruppamento di potrebbe effettuare il conteggio. L'output:
1 |1 |Laurea
2 |1 |Diploma
rivela che al progetto hanno preso parte un laureato e un diplomato.