Introduzione e modello di dati

8 settembre 2017

Nel panorama NoSQL, un posto di particolare rilievo è riservato ai database a grafo. Questi, infatti, si differenziano dai comuni RDBMS non tanto per il modello di concorrenza adottato, bensì dal modello di dati. Neo4j, progetto nato nel 2003, è attualmente il database a grafo più utilizzato, seguito dall’ottimo OrientDB.

In queste lezioni, guideremo il lettore all’uso di Neo4j. Vediamone quindi subito le caratteristiche principali, che andremo ad approfondire in seguito:

  • modello di dati a grafo orientato con proprietà chiave-valore, supportate sia su nodi sia su relazioni. Questo modello è detto Property Graph;
  • due licenze: Community ed Enterprise. La prima è open source (GPL 3): il codice è scaricabile da GitHub. La versione Enterprise ha in più alcune funzionalità riguardanti monitoraggio, backup e gestione della concorrenza;
  • transazioni ACID (Atomiche, Coerenti, Isolate, Durabili). Quindi un modello di concorrenza robusto e affidabile anche per applicazioni enterprise – come per i tradizionali RBMS;
  • linguaggio di query dichiarativo (simile a SQL) denominato Cypher. Vedremo molti esempi su questo linguaggio, poiché rappresenta il modo più semplice ed espressivo per interagire con il database;
  • driver per interagire con i più diffusi linguaggi di programmazione;
  • possibilità di essere eseguito come server stand-alone, oppure integrato all’interno di una applicazione Java o altro linguaggio JVM (embedded).

Il modello Property Graph

In Neo4j possiamo memorizzare nodi e relazioni. Inoltre, entrambi possono avere un elenco di proprietà chiave-valore. La chiave è tipicamente una stringa che rappresenta il nome della proprietà, univoco per l’elemento di appartenenza, mentre il valore può essere:

  • un numero (intero o reale);
  • una stringa;
  • un array di numeri o di stringhe.

Per rappresentare le date, bisogna convertirle in stringa o in numeri (ad esempio il giorno giuliano), la scelta migliore dipende dal contesto di utilizzo. Per i dati binari si possono usare array di byte, anche se tipicamente si preferisce salvare i file in qualche punto raggiungibile e inserire in Neo4j una URL o un path.

Per quanto riguarda le caratteristiche dei nodi, il modello prevede che ognuno di essi:

  • abbia un ID univoco assegnato automaticamente da Neo4j al momento della creazione;
  • possa avere una o più Label (etichette) che servono a classificare i nodi e indicizzarli. Generalmente, le Label si usano per raggruppare entità dello stesso tipo: ad esempi, se uso Neo4j come database di un social network, potrei avere dei nodi con Label “Utente”, altri con label “Gruppi”, “Messaggi”, etc. Un nodo può avere più Label, aprendo la strada ad applicazioni interessanti, implementando una sorta di polimorfismo. I nodi con una certa Label possono essere indicizzati su certe proprietà, per velocizzarne la ricerca (come vedremo più avanti).

Ogni relazione invece:

  • ha necessariamente un tipo, che deve essere specificato dall’utente al momento della creazione. I tipi sono liberi, ad esempio posso creare tra due nodi una relazione di tipo AMICO_DI senza dover dichiarare tale tipo in precedenza;
  • ha necessariamente una direzione, ossia una relazione va da un nodo ad un altro e non è possibile creare relazioni senza verso. È possibile però fare query su relazioni indipendentemente dalla direzione delle relazioni, ad esempio per trovare i nodi che hanno la relazione AMICO_DI un certo nodo, indipendentemente dal fatto che le relazioni arrivino o partano da tale nodo.

Scenari di utilizzo

Il modello si presta a molti scenari di utilizzo. Innanzitutto, esso si presta a modellare situazioni che hanno intrinsecamente un modello a grafo, come ad esempio un’infrastruttura di una rete aziendale. Inoltre, grazie alla facilità di navigazione all’interno del grafo, questo modello è adatto a casi in cui siano necessarie ricerche semantiche, ad esempio nei sistemi di rilevazione di frodi. Segnaliamo che il sito GraphGist contiene molti esempi di grafi per Neo4j, completi di codice e interrogazioni per ricreare i database.

Se il modello si adatta bene a questi scenari in cui le strutture dati non sono facilmente inquadrabili in pochi schemi predefiniti, viceversa esso ha meno utilità quando ci sono molti dati ma in schemi molto omogenei, ad esempio un database dei movimenti di conto-corrente bancari oppure di carico-scarico magazzino.

Esempi

Consideriamo un database di un sito di e-learning. Gli utenti potrebbero essere rappresentati da nodi aventi la Label Utente, e le proprietà username e password. Nella sintassi di Cypher, ciò si scrive così:

(:Utente { username: 'htmluser@html.it', password: 'A4_2j4=' })

Come vedremo più in dettaglio in seguito, i nodi sono sempre rappresentati da parentesi tonde. Le proprietà si scrivono invece con la stessa sintassi di JSON: un elenco di attributi chiave:valore separati da virgola e racchiusi da parentesi graffe. Come impostazione predefinita, Neo4j non richiede che un nodo debba avere obbligatoriamente qualche proprietà, per cui è perfettamente legale creare un nodo senza etichette né proprietà. Però, come vedremo in seguito, è possibile introdurre vincoli, per cui possiamo richiedere che tutti i nodi con etichetta Utente abbiano una proprietà username o anche che tale proprietà sia univoca, ossia non esistano due utenti con lo stesso username.

Per indicare che un utente è iscritto ad un corso da effettuare entro una certa data possiamo, rappresentare l’iscrizione come relazione e il corso come un nodo con un’altra etichetta:

 (u)-[:ISCRITTO_A {scadenza: '2018-02-08'}]->(:Corso {nome: 'Corso di Neo4j'})

Abbiamo indicato la scadenza come una proprietà della relazione. Vediamo che con il segno della freccia -> abbiamo indicato la direzione della relazione.

A questo punto è facile realizzare query per trovare tutti gli utenti iscritti ad un corso, oppure gli utenti iscritti nel 2016:

MATCH (u)-[i:ISCRITTO_A]->(:Corso {nome: 'Corso di Neo4j'}) 
WHERE i.scadenza < '2016' 
RETURN u,i

Come si può intuire, il modello di dati è molto potente perché possiamo estendere il grafo in tantissimi modi creando nuovi tipi di relazioni tra nodi, oppure possiamo navigare tra le informazioni presenti nel grafo in modo molto semplice, percorrendo le relazioni.

Nelle prossime lezioni vedremo quali sono le potenzialità del modello e che uso se ne può fare grazie a Cypher.

Tutte le lezioni

 

1 2 3... 16

Se vuoi aggiornamenti su Introduzione e modello di dati inserisci la tua e-mail nel box qui sotto:
Tags: ,
 
X
Se vuoi aggiornamenti su Introduzione e modello di dati

inserisci la tua e-mail nel box qui sotto:

Ho letto e acconsento l'informativa sulla privacy

Acconsento al trattamento dei dati per attività di marketing