Scuola Politecnica e delle Scienze di Base Corso di Laurea in Ingegneria Informatica Elaborato finale in Basi di Dati Database NoSQL: OrientDB Anno Accademico 2015/2016 Candidato: Stefano De Vincenzo matr. N46001320 Ai miei genitori, cui devo ogni cosa. Indice Introduzione 1 Dai 1.1 1.2 1.3 1.4 1.5 1.6 1.7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 2 3 4 5 5 7 8 8 9 11 11 15 2 OrientDB 2.1 Struttura OrientDB . . . . . . . . . . . . . . . . . . 2.1.1 Classi astratte . . . . . . . . . . . . . . . . . 2.1.2 Sicurezza . . . . . . . . . . . . . . . . . . . . 2.1.3 Regole . . . . . . . . . . . . . . . . . . . . . . 2.1.4 Ruoli . . . . . . . . . . . . . . . . . . . . . . 2.1.5 Utenti . . . . . . . . . . . . . . . . . . . . . . 2.1.6 Sicurezza a livello di record . . . . . . . . . . 2.2 Esempio applicativo . . . . . . . . . . . . . . . . . . 2.2.1 Primo approccio ad OrientDB . . . . . . . . . 2.2.2 Creazione della base di dati . . . . . . . . . . 2.2.3 Prima potenzialità: classi schema-less . . . . 2.2.4 Seconda potenzialità: noncuranza dei valori . 2.2.5 Terza potenzialità: campo embedded . . . . . 2.2.6 Quarta potenzialità: campi containers . . . . 2.2.7 Analogia a schemi relazionali: vincoli . . . . . 2.2.8 Analogia a schemi relazionali: relazioni-JOIN 2.3 OrientDB: graph-database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 18 19 19 19 20 20 21 21 21 24 26 29 30 30 31 33 36 1.8 1.9 1.10 1.11 database Relazionali ai database NoSQL Cos’è un database relazionale . . . . . . . . . Il modello ER . . . . . . . . . . . . . . . . . . SQL . . . . . . . . . . . . . . . . . . . . . . . Cos’è un database NoSQL . . . . . . . . . . . Perché sono nati i database NoSQL . . . . . . I vantaggi dei database NoSQL . . . . . . . . NoSQL: a cosa si rinuncia . . . . . . . . . . . 1.7.1 Teorema CAP . . . . . . . . . . . . . Come cambiano le regole: da ACID a BASE . Big Data . . . . . . . . . . . . . . . . . . . . . Tipologie di database NoSQL . . . . . . . . . Dove non si usa un database NoSQL . . . . . 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Conclusioni 40 Bibliografia 41 Introduzione L’obiettivo di questa tesi è quello di fornire nella maniera più chiara e semplice possibile una descrizione completa di una nuova tecnologia ancora in fase di sviluppo, quella dei database NoSQL. Evidenzieremo i motivi per i quali tale tecnologia risulta necessaria al giorno d’oggi in alcuni contesti, le migliorie che apporta ad alcune dinamiche e, contemporaneamente, i difetti che presenta. Con la semplificazione dell’accesso alla rete, con la possibilità per chiunque di possedere un terminale che possa collegarsi ad Internet e quindi con l’aumento di utenza, applicazioni, con la semplicità offerta dalla rete nel gestire/fornire molteplici servizi e con la nascita del Cloud-Computing, è diventato necessario per ogni tipo di fornitore di servizi, dal piccolo imprenditore alle grandi aziende, avere la possibilità di memorizzare e manipolare in maniera semplice ed efficace qualsiasi tipo di informazione: strutturata e non strutturata che sia. • I dati strutturati sono quelli che possono essere memorizzati nei database relazionali; possono cioè risiedere all’interno di tabelle e schemi attraverso relazioni e vincoli. • I dati non strutturati non hanno la possibilità di essere conservati all’interno di tabelle fisse ma hanno bisogno di essere gestiti attraverso tecniche ad hoc; tali tecniche fanno parte di quella branca dell’informatica denominata Information-Retrieval. Nelle applicazioni software moderne c’è sempre più spesso la necessità di maneggiare una gran quantità di dati che risultano essere non strutturati. In questo scenario, i database relazionali, nati per gestire solo dati schematizzabili, non risulterebbero la scelta progettuale più corretta. E’ questo uno dei principali motivi che ha contribuito allo sviluppo dei database NoSQL. I database NoSQL sono un prodotto ancora sostanzialmente giovane, realizzati per soddisfare le moderne necessità per quanto riguarda la gestione di grandi quantità di dati, spesso senza uno schema fisso o con uno schema che può variare molto quando il software è in fase di sviluppo. Per di più tutti questi dati possono essere relazionati tra loro in molteplici modi. Un esempio pratico e lampante lo si trova oggigiorno nei social networks. Prima di entrare nel merito dei database NoSQL, daremo un accenno a quello che è il mondo dei database relazionali. Successivamente differenzieremo i due macro approcci evidenziando caratteristiche e vantaggi di ognuno di essi. Infine ci concentreremo su OrientDB, un database non relazionale, attraverso cui presenteremo un piccolo esempio pratico che ci permetterà di evidenziare quanto sia semplice, intuitivo e soddisfacente lavorare con un database di questo tipo. Capitolo 1 Dai database Relazionali ai database NoSQL Per comprendere al meglio le dinamiche che hanno forzato la realizzazione dei database NoSQL, risulta necessario mostrare le caratteristiche del modello che, fino a pochi anni fa, dominava sul mercato: il modello relazionale. L’intento di questo capitolo è, appunto, fornire una breve ma calzante descrizione degli aspetti fondamentali di tali database, sottolineando quelle che sono le caratteristiche oggigiorno più proibitive per il loro utilizzo. 1.1 Cos’è un database relazionale Il cuore di un database relazionale è il DBMS (Data Base Management System/Sistema di gestione di una base di dati). Concettualmente è possibile inquadrare il DBMS assimilandolo ad un sistema operativo, ovvero quel software che, interfacciandosi con l’utente, semplifica la comunicazione con l’hardware sottostante; allo stesso modo lavora un DBMS per una base di dati. L’unione tra il database ed il DBMS dà vita al cosiddetto RDBMS. I compiti fondamentali di un DBMS sono molteplici e si raggruppano nelle parole chiave DDL e DML: • DDL sta per Data Definition Language ed indica il linguaggio con il quale si definisce come i dati sono organizzati in informazioni. Alcuni esempi sono: CREATE TABLE, ALTER TABLE, DROP TABLE, CREATE SCHEMA, CREATE TABLE ecc. • DML è l’acronimo di Data Manipulation Language e si riferisce al linguaggio con il quale il DBMS si interfaccia con i dati all’interno del database. Attraverso il DML è possibile operare sulla base dati sia per interrogarla che, eventualmente, modificarla. Alcune istruzioni sono: INSERT INTO, SELECT, SET, UPDATE ecc. Le istruzioni che permettono tali comunicazioni sono le cosiddette query. 2 CAPITOLO 1. DAI DATABASE RELAZIONALI AI DATABASE NOSQL 3 Le query sono il linguaggio attraverso il quale si interagisce con una base di dati; l’interazione prevede le operazioni di inserimento, modifica, cancellazione e visualizzazione. Tutte le operazioni svolte su una base di dati relazionale prendono il nome di transazioni. Il concetto cardine del modello relazionale sta nel soddisfacimento di quattro proprietà, le ACID, da parte di ogni singola transazione. Tali proprietà sono: à: ogni transazione è indivisibile; essa deve essere eseguita (comAtomicit mit) o annullata completamente (abort). onsistenza: in ogni momento il database deve trovarsi in uno stato conC sistente; devono quindi essere rispettati tutti i vincoli di integrità dei dati come quello di chiave primaria, vincoli di tupla, vincoli di integrità referenziale. ciascuna transazione deve essere eseguita come se fosse l’unica IUnasolamento: presente nel database; deve quindi risultare indipendente da tutte le altre. transazione che fallisce non deve interferire con le altre transazioni presenti. urabilità/Persistenza: indica la capacità di non perdere i cambiamenti D dovuti ad una qualsiasi query. I risultati di una transazione sono quindi permanenti, anche in presenza di failures. 1.2 Il modello ER Il binomio costituito dalla base di dati e dalle applicazioni che operano su essa prende il nome di applicazione di base di dati. La progettazione di una applicazione di base di dati prevede: 1. La progettazione della base di dati vera e propria; 2. Lo sviluppo delle applicazioni che dovranno interagire. La prima parte della progettazione della base di dati viene chiamata progettazione concettuale dato che viene fatta ad un alto livello di astrazione attraverso cui si modella progettando il database in maniera indipendente dal modello logico dei dati. In tale fase si traducono le informazioni risultanti dall’analisi di un determinato dominio in uno schema concettuale. La seconda fase è chiamata progettazione logica la quale traduce il modello concettuale in un particolare modello logico dei dati. Infine si passa alla progettazione fisica. Uno dei concetti chiave su cui si fondano i database relazionali è quello di un particolare modello di progettazione concettuale chiamato ER (Entity-Relationship), formalizzato dal prof. Peter Chen nel 1976. I concetti cardine di tale modello CAPITOLO 1. DAI DATABASE RELAZIONALI AI DATABASE NOSQL 4 sono quello di Entità, Attributi e Relazioni. Le entità rappresentano classi di oggetti che posseggono delle proprietà comuni ed hanno esistenza autonoma all’interno dell’applicazione di interesse. Si parla quindi di occorrenza di entità per riferirsi ad un concetto che esprime un oggetto esistente nel mondo reale. Un’occorrenza di entità ha un’esistenza indipendente dalle proprietà ad essa associate. Gli attributi sono appunto le proprietà che descrivono un’entità. Essi possono essere semplici o composti. Un’associazione rappresenta il legame esistente tra due o più entità. Proprio perché ad una associazione possono partecipare più entità, si parla di grado di una associazione. Anche le associazioni possono avere attributi oltre che cardinalità. Attraverso il concetto di attributo, possiamo mettere in evidenza un altro aspetto significativo dei database relazionali: lo schema. Uno schema di relazione è un nome, seguito dall’insieme degli attributi ad esso associato. Ad esempio: LIBRO(TITOLO, AUTORE, EDITORE). Uno schema ci permette di fornire una descrizione pratica di un’entità. L’attributo di consistenza esposto precedentemente nelle proprietà ACID si riflette proprio sugli schemi; ogni istanza degli stessi infatti deve rispettare un vincolo di integrità (IC/Integrity Constraint) attraverso cui i dati dello schema siano corrispondenti al modello descritto. Riassumendo: nei database relazionali i dati reali assumono valore di entità; più entità possono avere relazioni ed ogni entità possiede degli attributi. Le entità si traducono in maniera pratica in tabelle e le tabelle memorizzano dati ben definiti in termini di tipo, dimensione ed altri vincoli. 1.3 SQL SQL è l’acronimo di Structured Query Language. Esso è il linguaggio utilizzato dai DBMS relazionali attraverso cui è possibile comunicare con qualsiasi database. SQL nasce (con l’acronimo SEQUEL) grazie ad IBM ed in particolare con Donald Chamerlin e Raymond Boyce nel 1974. Nel 1986 è stato adottato come standard dall’ANSI e nel 1987 da ISO. La prima versione prende il nome di SQL/86 poi evolutasi in SQL-92 ed infine in SQL-2003. La differenza fondamentale con gli altri linguaggi (procedurali) risiede nel fatto che SQL risulta essere dichiarativo: l’utente decide cosa fare e non specifica anche il come, ovvero l’ordine di esecuzione. CAPITOLO 1. DAI DATABASE RELAZIONALI AI DATABASE NOSQL 5 Esempio Query (1): INSERT INTO utenti VALUES (‘123’,‘Stefano’,‘De Vincenzo’, to date(‘01-11-1992’,‘dd-mm-yyyy’),‘Italia’,‘Napoli’,80126); Esempio Query (2): DELETE FROM utenti WHERE nome LIKE ‘S%’; La prima query si occupa dell’inserimento di alcuni valori all’interno di una tabella chiamata utenti. La seconda query elimina dalla suddetta tabella tutte le righe il cui campo nome inizia con la lettera S. 1.4 Cos’è un database NoSQL Il termine NoSQL compare per la prima volta nel 1998 per merito del professor Carlo Strozzi, grazie alla presentazione del suo database Strozzi NoSQL relational database: un database molto leggero di tipo relazionale che però non si fondava sul linguaggio SQL. Oggi il termine NoSQL è utilizzato per riferirsi ad ogni datastore che non segue il modello RDBMS cioè dove il dato immagazzinato non è relazionale e non viene utilizzato SQL come linguaggio per le query. Molti di essi in realtà supportano anche SQL, pur prediligendo altri linguaggi; per questo motivo il significato più corretto dovrebbe essere Not Only SQL. Inoltre ci si riferisce ai database che non seguono i principi RDBMS soprattutto per quanto riguarda le proprietà ACID; i database non relazionali infatti sono progettati specificatamente per fornire velocità e scalabilità, attributi non certamente garantiti dalle ACID. Alcuni dei primi prodotti NoSQL nascono per merito dell’Apache Software Foundation (logo in fig.1.1), una comunità no-profit dedita allo sviluppo di moltissimi progetti software; ne citiamo alcuni: • Hadoop: è un framework scritto in Java che permette un elevato accesso ai dati; lavora su applicazioni distribuite. • Lucene: programmato anch’esso in Java; è un’ API utilizzata per il retrieval di informazioni; Wikipedia ne fa uso. • Cassandra: DBMS NoSQL; utilizzato da Digg e Twitter. • ZooKeeper: applicazione progettata per fornire servizi di configurazione e sincronizzazione ai sistemi distribuiti; si tratta di un insieme di processi interconnessi tra loro la cui comunicazione avviene sotto forma di scambio di messaggi. 1.5 Perché sono nati i database NoSQL Il modello relazionale è tuttora largamente il più utilizzato. Tuttavia a causa del proliferare, ormai da anni, di software che lavorano su quantità enormi di dati CAPITOLO 1. DAI DATABASE RELAZIONALI AI DATABASE NOSQL 6 Figura 1.1: Logo dell’Apache Software Foundation provenienti da domini dinamici, quest’ultimo inizia a mostrare tutti i suoi limiti. Un esempio lampante è quello dei social network che si basano sull’utilizzo di molteplici varietà di dati i quali, chiaramente, necessitano di una particolare gestione che si differenzia notevolmente da quella di un classico database RDBMS. Si parla infatti di dati non più “normalizzabili” cioè dati che difficilmente sono coerenti all’interno di una/uno entità/schema RDBMS. Un altro aspetto critico è quello dell’elevata mole di dati. Sappiamo che una delle operazioni fondamentali dei database relazionali è quella di JOIN che serve a combinare (unire) le tuple di due o più relazioni di un database tramite l’operazione di congiunzione. E’ evidente che con l’aumentare della dimensione del dataset, l’operazione di JOIN cresce linearmente/esponenzialmente, fino a diventare ingestibile. E’ a questo punto che nasce l’esigenza di poter lavorare con un database diverso, che riesca ad integrare tutti i dati eterogenei che gli vengono forniti e che sia capace di mantenere alte le prestazioni anche con l’aumentare del dataset alla base. Un database che quindi si sappia evolvere, non più statico e legato a schemi predefiniti. Che supporti anche l’assenza di vincoli e integrità referenziale. Tutto questo, magari, supportando il modello ACID. Abbiamo appena visto un quadro generale del perché il movimento NoSQL si sia sviluppato cosı̀ rapidamente. Vogliamo adesso raggruppare in maniera semplice e schematica i fattori negativi legati ai database relazionali e vedere, nel prossimo paragrafo, come il modello NoSQL preveda di risolvere tali pecche. Abbiamo sintetizzato le principali problematiche del modello relazionale in tali caratteristiche evidenziate di seguito: ↓ Inflessibilità sugli schemi: i modelli RDBMS sono piuttosto inflessibili nel loro design. Molto spesso aggiungere una colonna è un’ operazione estremamente complicata. E’ possibile creare nuove tabelle ed accrescere la complessità introducendo relazioni tra le tabelle stesse. ↓ Query complesse: molto spesso l’interazione con una base di dati relazionale CAPITOLO 1. DAI DATABASE RELAZIONALI AI DATABASE NOSQL 7 avviene mediante query complesse, chiamate JOIN-queries, difficili da implementare e che comportano un elevato consumo di risorse per essere eseguite. ↓ Aggiornamento dei dati: aggiornare i dati nelle tabelle è probabilmente uno degli scenari più critici, specialmente se ciò deve essere fatto in una transazione; inoltre mantenere a lungo una transazione fa calare le performance. Esiste poi il rischio di opf (one point failure) nel caso in cui si vogliano propagare gli aggiornamenti a nodi vicini e il sistema non supporti molteplici scritture da parte di un master o la scrittura simultanea su più nodi. ↓ Scaling (scalabilità) orizzontale: precisiamo che quando si parla di scalabilità si intende la capacità di un sistema informatico di lavorare, conseguentemente al fatto che il carico di lavoro diminuisca/aumenti. Lo scaling verticale prevede l’aumento delle prestazioni del sistema andando ad operare sulle risorse hardware già presenti mentre lo scaling orizzontale si basa sull’aumento di postazioni hardware. Lo scaling orizzontale, appunto, comporta tutta una serie di problemi che riguardano la gestione di grandi moli di dati come la consistenza, la comunicazione e la sincronizzazione. I database relazionali hanno sempre fatto affidamento allo scaling verticale che ha portato ad avere postazioni sempre più potenti; è evidente però che con l’aumento di utenza si è reso necessario scalare anche orizzontalmente per fornire prestazioni più elevate in termini di accesso e maggiore sicurezza sui dati. Lo scaling orizzontale però entra in conflitto con le restrizioni del modello ACID, legato indissolubilmente alla consistenza dei dati. ↓ Natura sempre più dinamica dei domini: come abbiamo già avuto modo di accennare, i database relazionali si basano sul modello ER che gestisce i suoi dati tramite il concetto di entità, difficilmente associabile a tutti i tipi di dati gestiti da un database NoSQL. ↓ Gestione di grandi moli di dati: le basi di dati relazionali, in genere, non sono in grado di gestire (o meglio di gestire in maniera ottimale) elevate quantità di dati; questo perché si tiene conto del modello ACID che predilige (come vedremo a breve) consistenza dei dati rispetto alla disponibilità immediata degli stessi. 1.6 I vantaggi dei database NoSQL Presentiamo i vantaggi dei database NoSQL anch’essi in maniera schematica, in modo da poter ottenere un confronto diretto con le problematiche esposte precedentemente: ↑ Strutturazione dei dati: NoSQL non adopera le strutture ben poco flessibili dell’approccio relazionale. Questi nuovi approcci, infatti, conferiscono una maggiore centralità alle informazioni e alla loro varietà, supportando l’uso di dati non omogenei pur mantenendo le possibilità di interrogazione, analisi ed elaborazione efficiente; si parla di Schemaless data representation. ↑ Scalabilità: a differenza dei database relazionali, quelli di tipo NoSQL sono generalmente basati su strutture fisiche che si prestano meglio alla distribuzione CAPITOLO 1. DAI DATABASE RELAZIONALI AI DATABASE NOSQL 8 dei dati su più nodi di una rete (sharding), permettendone pertanto un’espandibilità maggiore. Tutta la complessità che è richiesta per le transazioni oriented RDBMS non esiste nei database NoSQL che, quasi sempre, non sono conformi alle ACID (CouchDB e Neo4j sono esempi particolari di database NoSQL conformi alle ACID). ↑ Prestazioni: la maggiore distribuzione dei dati sulle reti, dovuta allo scaling orizzontale, è un elemento che permette migliori performance. Le tecnologie RAID sono un esempio lampante di come la replica dei dati su più strutture permetta di rispondere più rapidamente a tutte le richieste simultanee. Non è un caso, quindi, che la crescita del movimento NoSQL sia coincisa con la diffusione dei social network, caratterizzati da un elevato numero di accessi simultanei. ↑ Flessibilità nella progettazione: la struttura flessibile usata nei database NoSQL non obbliga necessariamente ad avere dati stereotipati durante la progettazione ma lascia liberi i programmatori di risolvere eventuali casi particolari direttamente in fase di sviluppo dell’applicazione. In fase di sviluppo è possibile partire con NoSQL e migrare a RDBMS e viceversa. E’ possibile anche avere scenari in cui serve un mix dei due database. Ad esempio Netflix è passata dall’avere Oracle RDBMS ad Apache Cassandra. ↑ Tempi di sviluppo: i database NoSQL non hanno il supporto per creare relazioni o avere chiavi esterne. Non ci sono più query complesse e operazioni di JOIN. Questo comporta che affinché una query possa attraversare più tabelle è necessario implementare più query ma più semplici. Tutto ciò contribuisce ad una drastica diminuzione dei tempi di sviluppo. 1.7 NoSQL: a cosa si rinuncia Uno degli aspetti più critici dei database NoSQL è quello che viene messo in luce dal teorema CAP. Ciò che dimostra tale teorema è probabilmente il fattore principale che influenza la scelta, in fase di pre-progettazione, della tipologia di database (RDBMS o NoSQL) da utilizzare. 1.7.1 Teorema CAP Il teorema CAP (o teorema di Brewer) dimostra come sia impossibile per un qualsivoglia sistema informatico distribuito, riuscire a garantire contemporaneamente questi tre aspetti (fig.1.2): • Consistenza: ogni nodo ha la garanzia di osservare il dato corretto in ogni momento. • Disponibilità: garantisce che ad ogni richiesta effettuata, venga fornita una risposta (positiva o negativa). • Tolleranza di partizione: indica la capacità del sistema distribuito di continuare a funzionare nonostante ci siano stati errori e/o perdite di messaggi. CAPITOLO 1. DAI DATABASE RELAZIONALI AI DATABASE NOSQL 9 Inizialmente nato come congettura esposta all’Università della California dallo scienziato informatico Eric Brewer (figura molto nota nel campo dell’IT ed attualmente professore di ruolo all’università di Berkeley in California), nel 2002, grazie alla dimostrazione fornita da Seth Gilbert e Nancy Lynch del MIT, ha assunto il rango di teorema. Il teorema, appunto, afferma che un sistema distribuito può essere in grado di soddisfare contemporaneamente solo due delle tre proprietà presentate. Il teorema CAP è centrale nel discorso che stiamo affrontando perché i database NoSQL, basandosi sul modello di consistenza BASE che vedremo a breve, forniscono elevata dispoFigura 1.2: Teorema CAP nibilità e tolleranza a discapito della consistenza. Invece il modello RDBMS, legato al modello ACID, garantisce consistenza e tolleranza di partizione, a discapito della disponibilità. 1.8 Come cambiano le regole: da ACID a BASE Siamo in grado di analizzare gli aspetti più significativi dei database NoSQL identificando un modello di appartenenza, equivalente all’ACID dei database relazionali. Ciò grazie, ancora una volta, ad Eric Brewer che ha trasformato le regole ACID in regole BASE: • Basic Availability (alta disponibilità): per ogni request è garantita una response che può indicare il successo o il fallimento dell’esecuzione. • Soft state (stato dinamico): lo stato del sistema può cambiare più volte, anche senza input. • Eventual consistency (consistenza eventuale): il database può essere momentaneamente inconsistente ma alla fine risulterà tale. Questo significa che ciò che è immagazzinato non deve essere consistente necessariamente in fase di scrittura ma anche direttamente a tempo di lettura. I modelli ACID e BASE sono i due più comuni modelli di approccio per la creazione di un database (fig.1.3). Molto spesso vengono visti come modelli contrapposti e si cerca di stabilire quale sia il migliore in tutto e per tutto; in realtà entrambi hanno i loro vantaggi e svantaggi e quasi mai nessuno dei due si adegua perfettamente al caso d’uso. CAPITOLO 1. DAI DATABASE RELAZIONALI AI DATABASE NOSQL 10 Figura 1.3: ACID vs BASE ACID consente di operare in un ambiente sicuro per i dati garantendo alla fine di ogni transazione che i suoi dati si trovino in uno stato consistente e al sicuro sul disco. La scrittura consistente può essere una grande vantaggio per gli sviluppatori ma essa richiede meccanismi di locking che tipicamente presentano un pattern pesantissimo per molti dei casi d’uso. In effetti, in alcune applicazioni, le transazioni ACID sono più pessimistiche di quanto il dominio ne richieda effettivamente; in molti scenari reali si sono persi i requisiti per l’immediata consistenza e aggiornamento dei dati al fine di ottenere altri benefici come lo scaling e l’elasticità garantiti da BASE. Una base di dati BASE valorizza la disponibilità ma non offre garanzia di consistenza a tempo di scrittura. Oltretutto, il modello BASE fornisce meno garanzia dell’ACID: i dati saranno consistenti nel futuro o direttamente a tempo di lettura. Siccome il modello BASE offre poca consistenza, una scelta di questo tipo ricade sulle spalle degli sviluppatori che dovranno lavorare molto accuratamente sulla consistenza dei dati con cui lavorano. Cioè è essenziale essere familiari con il modello di sviluppo BASE prima di poter procedere a lavorare con esso; ciò può essere un grave svantaggio rispetto alla semplicità delle transazioni ACID. Il modello ACID risulta quindi perfetto nelle applicazioni che richiedono forte affidabilità e coerenza dei dati immessi al contrario del modello BASE che garantisce scaling elevato e disponibilità. CAPITOLO 1. DAI DATABASE RELAZIONALI AI DATABASE NOSQL 1.9 11 Big Data I database NoSQL trovano molto spazio nelle applicazioni Big Data grazie alla semplicità della struttura, allo scaling orizzontale più semplice e alla maggiore disponibilità fornita. Quando si parla di Big Data ci si riferisce ad una raccolta dati molto estesa, non solo in termini di volume, ma anche (e soprattutto) in termini di eterogeneità dei dati; tutto supportato da elevate velocità operazionali. I dati con cui si lavora sono strutturati e non strutturati; basti pensare a tutte le informazioni reperite dai social come messaggi, conversazioni, foto, video, registrazioni vocali oppure a dati di altro tipo come dati di geo-localizzazione, immagini, email ecc. Si parla quindi di domini al cui interno è presente una mole gigantesca di dati che può essere dell’ordine degli Zettabyte. Associato ai Big Data c’è il concetto delle cinque V (fig.1.4), ovvero cinque parole chiave che consentono di mettere in luce schematicamente tutti i concetti fondamentali di tale applicazione: • Volume: si riferisce chiaramente alla mole di dati con cui opera il database. • Velocity (velocità): la velocità è attribuita sia alla capacità di generare dati nuovi, sia a come essi viaggiano all’interno della struttura. • Veriety (varietà): attribuito alla grande eterogeneità dei dati con cui si opera; si calcola che circa l’80% dei dati attuali mondiali risulta essere unstructured. • Veracity (veridicità): ossia la qualità dei dati intesa come il valore informativo che si riesce ad estrarre da essi. Si riferisce all’attendibilità (qualità e accuratezza) dei dati che viene messa a dura prova a causa dei moltissimi dati a disposizione. • Value (valore): la capacità di fornire servizi attraverso tale strumento e la trasformazione dei dati utilizzati in valori monetari. E’ chiaramente un elemento fondamentale di tutto il processo, che però si distacca dalle quattro precedenti proprietà che si focalizzano sulle prestazioni. Come abbiamo visto in precedenza, sono le soluzioni NoSQL quelle che forniscono la capacità ad un sistema di interagire con grandi volumi di dati eterogenei tra loro fornendo garanzia di velocità e scalabilità. E’ per questo motivo che non è permesso in questo ambito l’utilizzo dei RDBMS. 1.10 Tipologie di database NoSQL Essendo quello NoSQL un dominio ancora acerbo, non è ancora possibile riferirsi ad uno standard che riesca a dettare le linee guida per lo sviluppo di un database e che quindi riesca a classificare tutti i modelli già esistenti sul mercato. In generale però, tra le decine e decine di esempi applicativi che ci vengono CAPITOLO 1. DAI DATABASE RELAZIONALI AI DATABASE NOSQL 12 Figura 1.4: Le cinque V forniti, riusciamo ad evidenziare quattro categorie principali che si distinguono per il tipo di memorizzazione che implementano, ognuna delle quali soddisfa particolari esigenze: database a documenti (document-oriented-db), database a grafo (graph-oriented-db), database chiave/valore (key/value-db), database a colonna (column-oriented-db): • Document: una delle tipologie più diffuse grazie alla sua flessibilità. Sono utilizzati per archiviare (quindi inserire, ricercare e manipolare) grandi quantità di dati eterogenei. I dati vengono memorizzati come records (righe) come nei RDBMS; i records però possono aderire o meno ad uno specifico schema. Fornisce infatti la possibilità di avere schemi variabili o anche documenti senza schemi: due records, ad esempio, possono avere set completamente differenti di campi o colonne. Il vantaggio principale risulta proprio quello di non avere schemi da seguire. Ciò è molto utile in applicazioni web dove c’è bisogno di memorizzare differenti tipi di contenuto che può evolvere nel tempo. Inoltre la ricerca attraverso molteplici tipi di entità risulta molto più semplice se comparata a quella dei relazionali. Infatti adesso scompare il concetto di tabella il che comporta che una query possa attraversare i record a prescindere dal contenuto sottostante; in altre parole la query è effettuata all’intero database. Un altro grande vantaggio risulta quello di poter esprimere i dati attraverso il formato JSON. Il JSON (Javascript Object Notation) è un formato utilizzato per l’interscambio di dati fra applicazioni client-server. Attraverso i documenti JSON è possibile memorizzare i dati in maniera schemaless. Di seguito riportiamo un esempio di JSON: {” S t u d e n t e ” : [{ ” M a t r i c o l a ” : ” N46001320 ” , ”Nome ” : ” S t e f a n o De Vincenzo ” , ” Eta ” : 2 3 CAPITOLO 1. DAI DATABASE RELAZIONALI AI DATABASE NOSQL 13 }] } Un altro documento potrebbe avere un insieme di attributi molto diverso; ad esempio: {” S t u d e n t e ” : [{ ” M a t r i c o l a ” : ” M53192990 ” , ”Nome ” : ” Mario ” , ”Cognome ” : ” R o s s i ” , ” Eta ” : 3 5 , ” Citta ”:” Napoli ” , ” I n d i r i z z o ” : ” Via Manzoni 86” }] } Alcuni dei database più popolari che implementano questo modello: Apache CouchDB, ApacheCassandra, Couchbase Server, Clusterpoint, DocumentDB, HyperDex, Lotus Notes, MarkLogic, OrientDB, Qizx, RethinkDB. MongoDB rappresenta il principale prodotto di questa serie e, secondo le stime, è uno dei database NoSQL più diffusi al mondo. • Graph: riproducono una delle strutture dati più duttili dell’informatica, soprattutto per alcune tipologie di problematiche. E’ particolarmente indicato quando si ha a che fare con dati fortemente connessi e si vuole avere una struttura performante per conoscere le relazioni tra i dati. I due elementi principali della struttura sono i vertici e gli archi : i primi contengono le informazioni mentre i secondi stabiliscono relazioni (link). Questo modello ha una grossa rilevanza in molti problemi che spaziano in vari domini: shortest path calculation, geodesic paths ed altri ancora. Se non esistono relazioni tra i dati che si immagazzinano, il modello risulta inutile. Alcuni esempi sono : Neo4J, AllegroGraph, InfiniteGraph, Giraph, MarkLogic, OrientDB, Virtuoso, Stardog. • Key/value: immagazzinano oggetti associando loro una chiave univoca che ne permetterà un agevole recupero. Nascono per gestire con la massima efficienza semplici coppie chiavevalore, ad esempio per essere utilizzati come cache; la base di dati è vista come una grossa hash-table. Sono utilizzati quando si predilige la velocità di accesso al dato, quindi particolarmente indicati quando si vogliono esaltare le operazioni CRUD (create, read, update, delete) e quando non c’è correlazione tra i dati da memorizzare. Redis è probabilmente uno dei prodotti di questo tipo più conosciuti; altri esempi sono: Oracle NoSQL Database, DynamoDB, MemcachedDB, CAPITOLO 1. DAI DATABASE RELAZIONALI AI DATABASE NOSQL 14 Aerospike, Couchbase, FairCom c-treeACE, FoundationDB, HyperDex, MemcacheDB, MUMPS, OrientDB, Riak, Berkeley DB. • Column-oriented: sono database che immagazzinano dati in sezioni di colonne a differenza dei RDBMS che utilizzano le righe. Uno dei più grandi vantaggi è quello di poter aggiungere colonne senza il bisogno di doversi preoccupare di inserire valori di default; questo giova alla flessibilità del modello permettendo di prepararsi per scenari futuri. Le colonne non sono definite a priori e possono essere diverse per ogni riga, aggiunte o rimosse dinamicamente. Quando si parla di database orientato alle colonne ci si riferisce sia alla struttura fisica vera e propria che ad una forte ottimizzazione per i carichi di lavoro. Un altro punto a favore riguarda le molteplici possibilità per quanto riguarda l’ottimizzazione per la compressione dei file memorizzati, concetto assente nei row-oriented nei quali applicazioni di questo tipo comporterebbero risultati minori Sottolineiamo in ogni caso che l’efficacia dei database dipende in gran parte dal carico di lavoro sottostante. Ad esempio operazioni che ricercano tutti i dati per un singolo oggetto (una riga) risultano lenti nei database a colonna mentre nei row-based un’operazione di questo tipo è effettuata in una singola lettura del disco. Ad ogni modo queste operazioni sono abbastanza rare; nella maggior parte dei casi viene ricercato solo un subset di un particolare oggetto. Forniamo un piccolo esempio per chiarire come opererebbe un database orientato alle colonne a differenza di uno orientato alle righe; supponiamo di voler memorizzare questo insieme di dati: Matricola N2301 M0091 L7623 Nome Lucia Mauro Marco Cognome Rossi Verdi Gialli In un database RDBMS (row-based) i valori sarebbero memorizzati in questo modo: N2301 , M0091 , L7623 , Lucia , Mauro , Marco , Rossi Verdi Gialli Un database orientato alle colonne, invece, serializza tutti i valori di una colonna assieme, poi serializza i valori della seconda colonna e cosı̀ via. Allora in un database di questo tipo i dati apparirebbero cosı̀: N2301 , Lucia , R os s i , M0091 , Mauro , Verdi , L7623 Marco Gialli CAPITOLO 1. DAI DATABASE RELAZIONALI AI DATABASE NOSQL 15 Tali strutture sono molto utilizzate nel campo dei Big Data in quanto forniscono un modello organizzato e flessibile. In particolare soluzioni di questo tipo sono state adottate da Facebook, Google ed Amazon. La prima applicazione ad usare questo tipo di memorizzazione fu, nel 1969, TAXIR: un’applicazione per la biologia dedita all’information retrieval. Alcuni esempi di questo modello sono: Apache Cassandra, Hypertable, HBase, Google Datastore, Big Table, SimpleDB, Accumulo, Druid, Vertica, Microsoft SQL Server 2012 Enterprise Edition. E’ bene notare che alcuni nomi compaiono in più categorie perché sono difficili da classificare oppure perché effettivamente implementano diverse modalità di storage; questi ultimi sono detti multi-storage. Alcuni di essi sono: Alchemy Database, ArangoDB, CortexDB, FoundationDB, MarkLogic, OrientDB. Come vederemo successivamente, OrientDB supporta le prime tre modalità di sviluppo. In figura 1.5 possiamo rapidamente confrontare i modelli appena descritti sulla base di alcune caratteristiche. Figura 1.5: Confronto database Esistono poi altre tipologie di database NoSQL quali gli Object Databeses e i Multidimensional Databases che però non saranno oggetto di questa discussione. 1.11 Dove non si usa un database NoSQL NoSQL non è certamente il modello che bisogna utilizzare in ogni applicazione né bisogna credere che abbia solo aspetti positivi; non è dunque la soluzione a tutti i problemi che possono incorrere utilizzando RDBMS. Il paradigma NoSQL pecca nel momento in cui il nostro dominio di interesse ha bisogno di transazioni sicure (tutto l’ambito finanziario), in cui istantaneamente CAPITOLO 1. DAI DATABASE RELAZIONALI AI DATABASE NOSQL 16 dobbiamo avere la possibilità di lavorare con dati consistenti; non è certamente un modello che si basa sull’affidabilità né tanto meno sull’integrità dei dati. Non è un modello utile quando il dominio di interesse non intende espandersi e soprattutto è sconsigliabile utilizzarlo se si lavora con dati facilmente normalizzabili cioè con applicazioni che fanno uso di dati predefiniti, che riescano quindi a rispettare i vincoli imposti da una tabella RDBMS. In breve: ↓ Non si utilizza in ambito economico-finanziario. ↓ Non si utilizza in ambienti che non hanno bisogno di espandersi. ↓ Non si utilizza in ambienti che fanno uso di dati “normalizzabili”. In fig.1.6 riassumiamo le principali caratteristiche dei due approcci. Figura 1.6: SQL vs NoSQL Capitolo 2 OrientDB Figura 2.1: Logo OrientDB OrientDB è un database NoSQL di tipo document-graph-key/value, scritto in Java e con licenza open source (Apache 2.0). Nasce in Italia (attraverso Orient Technologies) alla fine dell’ultima decade; oggi l’ultima versione disponibile è la 2.2.10 GA Community Edition, rilasciata il 15 Settembre 2016. OrientDB è un database molto versatile dato che permette l’utilizzo di una modalità di memorizzazione senza schema, con schema, oppure ibrida, supportando al tempo stesso il linguaggio SQL; gestisce i permessi di accesso alla struttura attraverso utenti, ruoli e regole. Utilizza un particolare algoritmo di indicizzazione derivato dall’Albero RB e dal B+tree chiamato MVRB-Tree, che gli permette di avere benefici sia nell’inserimento che nella ricerca. Siccome la JVM è l’unico requisito per utilizzare un server OrientDB, tale sistema può essere installato su ogni macchina che supporti la piattaforma JAVA. 17 CAPITOLO 2. ORIENTDB 18 Quali sono le funzionalità principali di OrientDB: • Supporto alle JOIN e alle ACID. • Supporto a multiple modalità di storage: document, graph, key/value. • Query SQL-like. • Libreria API per Java. • Supporto alla customizzazione del linguaggio (per scrivere funzioni Java personalizzate). • Console per amministrare tramite linea di comando. • Console web-based per amministrare tramite interfaccia grafica: OrientDBStudio. • Funzionamento embedded, in memory, client/server. • Supporto nativo a JSON. Alla base della struttura di questo database c’è la modalità document; ciò è dovuto al fatto che quando si parla di document ci si riferisce ad un tipo di dato generico che può essere associato a interi, stringhe, dati binari o addirittura riferimenti ad altri documenti. Attraverso tale modello siamo in grado di memorizzare i documenti in strutture molto flessibili che prendono il nome di collezioni. La potenzialità di questo modello è dovuta al fatto che un documento non ha necessariamente una struttura fissa (come accennato prima, OrientDB ha un approccio molto lasco) ma può contenere un numero variabile, nel numero e nel tipo, di campi. 2.1 Struttura OrientDB In OrientDB i clusters sono le strutture principali utilizzate per organizzare i dati. E’ possibile pensare ai clusters come ad un gruppo di records. Nel mondo relazionale non esiste un concetto simile. I clusters possono non avere uno schema e colonne, i loro records sono chiamati documents e ogni documento può essere differente da altri che appartengono allo stesso clusters. Ci sono due tipi di clusters: physical e in-memory. Il primo è persistente, il secondo volatile, ovvero viene distrutto quando il server va in shutdown. Per ogni clusters OrientDB crea uno o più file. Il concetto di classe si posiziona ad un grado più elevato di astrazione rispetto ai clusters ed è assimilabile come il duale di una tabella nel mondo relazionale, cioè una struttura che immagazzina records. Le classi possono essere: CAPITOLO 2. ORIENTDB 19 • Schema-full (vincoli obbligatori). • Schema-less (non sono definiti vincoli). • Mixed-mode. Particolarità: i records di una classe possono essere memorizzati in differenti clusters. Ciò è utile quando si ha un largo dataset di records che risulta conveniente partizionare. All’atto della creazione di una classe, OrientDB la definisce schema-less. Questo significa che ogni record appartenente ad una classe può avere differenti campi di qualsiasi tipo di dato supportato e può accadere che due o più records possano avere gli stessi campi ma con differenti tipi di dato. Chiaramente OrientDB supportando anche le classi schema-full, cioè classi in cui sono dichiarati esplicitamente i tipi di dato a loro associati, può specificare se sono permessi o meno valori nulli e se sono obbligatori o opzionali. E’ evidente che lo schema-less ha il vantaggio di poter essere utilizzato nei casi in cui non si conosce quale valore verrà inserito, come un campo che deve memorizzare un input arbitrario dell’utente. Lo schema-full invece controllerà la validità dell’inserimento alzando un’eccezione se il valore non è coerente. I tipi di dato disponibili in OrientDB si suddividono in due macro categorie: semplici e containers: • I tipi di dato semplici sono: binary, boolean, byte, date, double, embedded, float, integer, long, short, string, link. • I tipi di dato containers sono: linklist, linkset, linkmap, embeddedlist, embeddedset, embeddedmap. 2.1.1 Classi astratte Come nel paradigma OOP è presente il concetto di classe astratta. Le classi astratte non sono associate ad alcun cluster (cluster ID = -1) e non possono memorizzare records ma sono utili per definire le proprietà che ogni classe derivata dovrà avere. 2.1.2 Sicurezza OrientDB ha un modello di sicurezza molto solido che si basa su tre aspetti: utenti, ruoli e regole. Ogni database ha i suoi utenti associati, ogni utente ha uno o più ruoli e ogni ruolo ha delle regole da rispettare (fig.2.2). 2.1.3 Regole Le regole definiscono i criteri di sicurezza applicati a risorse specifiche. Una regola allora è l’insieme di una risorsa e dell’operazione applicabile a quella risorsa stessa. Le operazioni consentite sono: • NONE 0 bitmask # 0000 CAPITOLO 2. ORIENTDB 20 • CREATE 1 bitmask # 0001 • READ 2 bitmask # 0010 • UPDATE 4 bitmask # 0100 • DELTE 8 bitmask # 1000 • ALL 15 bitmask # 1111 E’ possibile effettuare combinazioni di più regole al fine di personalizzarle. Ad esempio: READ + UPDATE + DELETE= 2 + 4 + 8 = #1110 2.1.4 Ruoli OrientDB utilizza i ruoli per capire se una operazione è consentita ad uno specifico utente. Ogni ruolo è associato ad una o più regole. I ruoli di default sono tre: admin (ha completo accesso al database), writer (può leggere, creare, aggiornare e cancellare records), reader (può solo leggere). E’ comunque possibile creare nuovi utenti e anche ruoli personalizzati. 2.1.5 Utenti Gli utenti sono memorizzati nella classe OUser, ad eccezione di quelli definiti nel file di configurazione XML (orientdb-server-config.xml ), ovvero admin, root e guest. Ogni utente deve avere una password e almeno un ruolo. I ruoli associati all’utente definiscono i diritti che ha l’utente per operare sul database. Di default ogni nuovo database ha tre utenti, associati ai tre ruoli dichiarati precedentemente (admin, writer e reader). Figura 2.2: Sicurezza in OrientDB CAPITOLO 2. ORIENTDB 2.1.6 21 Sicurezza a livello di record La sicurezza a livello di record è una delle features più potenti di OrientDB. Utilizzando questa funzionalità gli sviluppatori possono applicare un accesso molto fine attraverso dei permessi di sicurezza associati ad ogni singolo record di una classe. Con questa funzione ogni record avrà dei campi addizionali che indicheranno se un utente può accedere e con quali privilegi. 2.2 Esempio applicativo Prima di inoltrarci nel vero e proprio esempio pratico, mostriamo quali sono i primi passi da effettuare per lavorare con OrientDB. Ricordiamo che l’ambiente di lavoro attraverso cui presentiamo l’esempio è la shell Windows. 2.2.1 Primo approccio ad OrientDB Scarichiamo una qualsiasi versione dal sito ufficiale: http://orientdb.com/ download/ Scompattiamo il file scaricato, rechiamoci nella cartella bin appena estratta e facciamo partire il server attraverso il comando: orientdb> start server.bat Fatto ciò ci colleghiamo, tramite console.bat, al database predefinito (fig.2.3) in questo modo: orientdb> connect remote:127.0.0.1/temp admin admin Figura 2.3: Connessione al server temporaneo OrientDB infatti fornisce un database predefinito chiamato temp. CAPITOLO 2. ORIENTDB 22 A questo punto vediamo cosa comporta la creazione di una classe (fig.2.4): orientdb> create class Prova e poi diamo il comando info. Figura 2.4: Creazione di una classe All’interno della tabella che contiene tutti i clusters presenti nel database appare un nuovo cluster denominato proprio come la nostra classe (in minuscolo). Notiamo poi che ogni cluster ha il suo proprio ID. Anche all’interno della tabella delle classi appare il nome della classe appena creata. Inoltre ci vengono mostrate delle informazioni sintetiche come ad esempio il numero di records inseriti (per adesso 0). Equivalentemente ai clusters, anche ad ogni record è associato un unico ID, denominato RID. Un RID ha una struttura del tipo #<cluster-id>:<position>. I RID sono dei veri e propri puntatori fisici ai records; ciò significa che le operazioni di attraversamento e di LINK attraverso i documenti sono molto veloci perché non ci sono overheads di consultazioni. Questa è la più grande feature di OrientDB rispetto ai database relazionali: conoscendo la posizione fisica dei records è possibile raggiungerli senza effettuare ricerche ad indice al contrario dei RDBMS che devono effettuare questo tipo di ricerca che, genericamente, è eseguita in un tempo O(log(n)) (logaritmico) mentre OrientDB esegue in O(1) (costante) (fig.2.5). Infine attraverso il comando ? possiamo visualizzare tutti i comandi disponibili. Una parte di essi è visibile in fig.2.6. CAPITOLO 2. ORIENTDB Figura 2.5: Classificazione complessità degli algoritmi Figura 2.6: Parte dell’elenco dei comandi disponibili 23 CAPITOLO 2. ORIENTDB 2.2.2 24 Creazione della base di dati Passiamo adesso all’esempio pratico vero e proprio. Supponiamo di voler creare una base di dati che gestisca (una piccola parte) dell’università di Napoli Federico II. Si vogliono gestire le relazioni che intercorrono tra i corsi di studio previsti dall’università e i diversi insegnamenti per ognuno di essi; inoltre gestiamo tutti i rappresentanti, ognuno per ogni tipo di insegnamento. Creiamo una prima classe (CorsoDiStudio) contenente i corsi di studio: • Ingegneria. • Economia. • Scienze. Creiamo poi una seconda classe (Insegnamento) contenente gli insegnamenti associati ad ogni corso di studio: • Ingegneria: informatica, civile, edile. • Economia: aziendale, finanza. • Scienze: chimica, fisica, biologia. Si ottiene una relazione 1−N tra CorsoDiStudio - Insegnamento e una relazione 1 − 1 tra Insegnamento - Rappresentante. In figura 2.7 abbiamo rappresentato il modello ER (non rappresentando gli attributi di ogni entità e le associazioni tra le stesse) del database. Figura 2.7: Modello ER Connettiamoci al server e creiamo una base di dati chiamata uniFEDERICOII di tipo document, utilizzando come memorizzazione la plocal (persistente). orientdb> create database remote:localhost/uniFedericoII CAPITOLO 2. ORIENTDB 25 root E5FFDC71E1BD6D3EF09832AD177EAD180A9558 E795E9B5298440ED54A3E8C38B document Per fare ciò abbiamo utilizzato l’account root per il quale ricaviamo la password (generata automaticamente) direttamente dal file XML orientdb-serverconfig.xml. Ci connettiamo al database appena creato (fig.2.8): orientdb> connect remote:localhost/uniFedericoII admin admin Figura 2.8: Connessione al server uniFedericoII Modifichiamo le password dei tre utenti predefiniti (admin, reader, writer) per consentire, in futuro, un accesso più semplice (fig.2.9): orientdb> update OUser set password=admin where name=“admin” orientdb> update OUser set password=reader where name=“reader” orientdb> update OUser set password=writer where name=“writer” Figura 2.9: Cambio password utenti predefiniti Creiamo le tre classi (fig.2.10): orientdb> create class CorsoDiStudio orientdb> create class Insegnamento CAPITOLO 2. ORIENTDB 26 orientdb> create class Rappresentante Figura 2.10: Creazione classi Siamo adesso in grado di poter interagire con il database per mostrare le principali potenzialità di OrientDB, presenti in ogni tipo di database NoSQL. 2.2.3 Prima potenzialità: classi schema-less Inizialmente le classi sono definite schema-less quindi è possibile inserirvi qualsiasi campo. Definiamo i tre corsi di studio (fig.2.11) inserendo un campo qualsiasi, ad esempio nome: orientdb> insert into CorsoDiStudio (nome) values (“Ingegneria”) orientdb> insert into CorsoDiStudio (nome) values (“Economia”) orientdb> insert into CorsoDiStudio (nome) values (“Scienze”) Figura 2.11: Popolamento classe CorsoDiStudio Effettuiamo a questo punto un’operazione di SELECT che stamperà a video tutta la classe per verificare la correttezza dell’inserimento precedente (fig.2.12): CAPITOLO 2. ORIENTDB 27 orientdb> select from CorsoDiStudio Figura 2.12: Esempio di SELECT su CorsoDiStudio Infine evidenziamo come le operazioni di SELECT possano essere effettuate, al fine di aumentare le prestazioni, direttamente sul RID del record di interesse (fig.2.13). L’esecuzione della query infatti passa da 0.019 secondi a 0.013 secondi. Figura 2.13: Confronto tra query CAPITOLO 2. ORIENTDB 28 Per proseguire con l’esempio pratico popoliamo anche la classe Insegnamento (fig.2.14) e la classe Rappresentante (fig.2.15). Figura 2.14: Popolamento classe Insegnamento Figura 2.15: Popolamento classe Rappresentante CAPITOLO 2. ORIENTDB 2.2.4 29 Seconda potenzialità: noncuranza dei valori Inseriamo nella tabella Insegnamento il numero di studenti che si iscrivono in media ogni anno (fig.2.16). Modifichiamo poi il campo numeroStudenti dell’ insegnamento Fisica e dichiariamo una stringa al posto di un intero. Figura 2.16: Inserimento del numero di studenti Osserviamo (fig.2.17) come l’inserimento di una stringa ove (dovrebbe) esserci un intero non causa alcun errore. Questa è una delle potenzialità più ricercate in quegli ambienti in cui si deve operare con dati eterogenei perché, appunto, ci consente di operare con qualsiasi dato senza la necessità di doverci occupare dei vincoli. Figura 2.17: Seconda potenzialità CAPITOLO 2. ORIENTDB 2.2.5 30 Terza potenzialità: campo embedded OrientDB fornisce la possibilità di utilizzare un campo di tipo document-embedded. Attraverso questo tipo possiamo associare a qualsiasi campo una stringa JSON. Inseriamo un nuovo rappresentante non considerando i campi nome e cognome ma andando ad inserire un campo embedded che ne specifichi la data ed il luogo di nascita (fig.2.18). Figura 2.18: Campo embedded Ovviamente anche i record embedded possono essere oggetto di una query (2.19). Figura 2.19: SELECT su campo embedded 2.2.6 Quarta potenzialità: campi containers I containers sono dei campi speciali che possono contenere un insieme di altri campi. Ci sono tre tipi di containers: set, list e map: • Set è un insieme di elementi non ordinato. CAPITOLO 2. ORIENTDB 31 • List è una sequenza ordinata di elementi. • Map è un insieme formato da coppie chiave/valore ove le chiavi sono stringhe e i valori possono essere qualsiasi tipo consentito, anche altri containers. Inseriamo un nuovo rappresentante di cui specifichiamo solo un campo container che memorizzerà i due indirizzi ove tale insegnante riceve gli studenti (fig.2.20). Figura 2.20: INSERT campo container Figura 2.21: SELECT campo containers Notiamo (fig.2.21) che effettuando una SELECT per stampare a video il valore di un campo container, non viene mostrato il contenuto del campo ma solo la sua cardinalità che in questo caso risulta essere pari a 2. Per mostrare il contenuto è sufficiente il comando: orientdb> select flatten(embset) from Rappresentante where embset is not null 2.2.7 Analogia a schemi relazionali: vincoli Fino ad ora abbiamo visto come si utilizzano le classi nella modalità schemaless. OrientDB però fornisce anche la possibilità di specificare per ogni campo, il tipo a cui deve sottostare; ovvero permette di creare un vincolo nello schema. Possiamo allora dichiarare se una classe deve essere schema-full o anche mixedmode. Supponiamo di voler associare ad ogni insegnamento l’anno in cui è stato creato, il cui valore deve essere una data; creiamo allora un vincolo (fig.2.22): CAPITOLO 2. ORIENTDB 32 orientdb> create property Insegnamento.annoFondazione date A questo punto inseriamo un nuovo insegnamento utilizzando come anno di fondazione un valore che non rispetti il vincolo, ad esempio una stringa: orientdb> insert into Insegnamento (tipologia,annoCreazione) values (“Economia delle Imprese Finanziarie”,“Duemiladue”) Figura 2.22: Esempio di vincolo non rispettato In figura 2.22 possiamo osservare come stavolta venga alzata un’eccezione causata dal fatto che si è tentato di convertire il valore Duemiladue in una data che, invece, ha un formato del tipo yyyy-MM-dd. Inoltre è possibile attraverso il comando STRICTMODE, evitare che una operazione di INSERT possa aggiungere dei campi precedentemente non dichiarati. Ad esempio se prima di dichiarare la classe in modalità STRICTMODE, provassimo ad inserire un nuovo campo anni, non ci sarebbe restituito errore (fig.2.23): Figura 2.23: STRICTMODE assente Utilizziamo allora la modalità STRICTMODE (fig.2.24): orientdb> ALTER CLASS Insegnamento STRICTMODE true CAPITOLO 2. ORIENTDB 33 In questo modo bisogna rispettare i campi presenti (Nome,Cognome,anni) e non è possibile aggiungerne altri. Infatti provando ad inserire dei valori del genere: orientdb> insert into Rappresentante (Nome,Cognome,anni,luogoNascita) values (“Stefano”,“De Vincenzo”,23,“Napoli”) alzeremmo un’eccezione dato che il campo luogoNascita non è stato preventivamente dichiarato. Figura 2.24: STRICTMODE presente 2.2.8 Analogia a schemi relazionali: relazioni-JOIN Nonostante anche in OrientDB esita il concetto di relazione, analogamente agli schemi relazionali, tale concetto assume sfumature differenti. Innanzitutto quando si crea una relazione in OrientDB, si stabilisce una connessione fisica tra i documenti. Ciò comporta che un’ operazione di JOIN che debba recuperare un documento associato ad un altro documento non abbia costo computazionale. Per questo motivo OrientDB risulta molto veloce quando si maneggiano milioni di records correlati tra loro. Le relazioni tra records possono essere di due tipi: • Referenced: utilizzati per creare associazioni tra documenti. • Embedded: sono relazioni più forti, simili alla composizione nei diagrammi UML. Questo tipo di relazione è utile per modellare i collegamenti tra documenti che hanno un ciclo di vita dipendente. Le associazioni 1 − 1 e 1 − N del nostro esempio possono essere create tramite un campo di tipo LINK che, accettando valori di tipo RID, crea un collegamento fisico tra i documenti. CAPITOLO 2. ORIENTDB 34 Nel nostro esempio ad ogni corso di studio sono associati uno o più insegnamenti. Ad ogni insegnamento è associato un solo corso di studio. Facciamo in modo che da ogni insegnamento sia possibile risalire al corso di studio. Per fare ciò utilizziamo: orientdb> create property Insegnamento.corsodistudio link CorsoDiStudio Vediamo come è stata modificata la classe Insegnamento: è stato aggiunto (fig.2.25) un nuovo campo chiamato corsodistudio di tipo LINK, collegato (LINKED) alla classe CorsoDiStudio ed è stato associato (fig.2.26) ad ogni insegnamento il corso di studio corrispondente che, inizialmente, è un campo vuoto (null). Figura 2.25: Associazione 1-N Figura 2.26: SELECT su associazione 1 − N CAPITOLO 2. ORIENTDB 35 Popoliamo inizialmente solo il campo corsodistudio relativo all’insegnamento Informatica (fig.2.26); effettuiamo poi una query per verificare che effettivamente appaia il corso di studio di ingegneria (fig.2.26). Figura 2.27: Comando TRAVERSE Associamo quindi ad ogni Insegnamento il CorsoDiStudio e utilizziamo il comando TRAVERSE (fig.2.27). Il comando TRAVERSE è un comando molto potente, di frequente utilizzato nei document database. Viene utilizzato spesso perché, assegnata una tabella, fornisce tutti i records collegati ad essa evitando di stampare due records identici. Risulta molto simile all’operatore JOIN dei database relazionali. Dopo aver associato ad ogni insegnamento il corrispettivo corso di studio, associamo il rappresentante (relazione 1 − 1) (fig.2.28). Figura 2.28: SELECT su tabella, post inserimento relazioni A questo punto riutilizziamo il comando TRAVERSE che ci consente in questo caso di rilevare tutto il database (fig.2.29). CAPITOLO 2. ORIENTDB 36 Figura 2.29: Comando TRAVERSE che rileva tutto il database 2.3 OrientDB: graph-database L’ultima applicazione che riportiamo riguarda OrientDB-graph, sottolineando che l’architettura a grafo discende direttamente da quella document dal momento che ogni nodo risulta essere un vero e proprio documento. Supponiamo di voler utilizzare tale struttura per fornire una sorta di mappa politica nella quale memorizzeremo le città italiane e, per ogni coppia di esse, ne evidenzieremo la distanza in chilometri. Per motivi pratici e per rendere il tutto più fruibile faremo un esempio molto semplice in cui consideriamo quattro città italiane: Napoli, Roma, Venezia e Firenze. Innanzitutto, come abbiamo fatto precedentemente, creiamo tramite shell Windows (dopo aver fatto partire server.bat) un nuovo database che chiameremo Mappa. Fatto ciò utilizziamo console.bat per connetterci (fig.2.30) al suddetto database. A questo punto passiamo alla vera e propria parte pratica: creiamo quindi i vertici (fig.2.30), ognuno corrispondente ad una città e, per ogni coppia di vertici (nel nostro caso il numero di coppie totali è pari a 6: Napoli-Roma, NapoliVenezia, Napoli-Firenze, Roma-Venezia, Roma-Firenze, Venezia-Firenze), un edge (fig.2.31) che ne rappresenterà la distanza. CAPITOLO 2. ORIENTDB Figura 2.30: Collegamento al database e creazione dei vertici Figura 2.31: Creazione dei collegamenti 37 CAPITOLO 2. ORIENTDB 38 Accediamo tramite browser al database appena creato attraverso l’indirizzo http://localhost:2480/, scegliendo il database Mappa e utilizzando le credenziali di accesso admin admin (fig.2.32). Figura 2.32: OrientDB studio Accedendo alla sezione Graph possiamo visualizzare la struttura grafica del database (fig.2.33). Infine presentiamo un’applicazione di una query ad un database di questo tipo. Ad esempio potremmo ricercare tutte le città (e le relative distanze) che sono collegate ad una fornita dall’utente (fig.2.34). CAPITOLO 2. ORIENTDB 39 Figura 2.33: OrientDB graph La query seleziona i nomi delle città tra i risultati della TRAVERSE e della WHERE. In particolare l’operazione di TRAVERSE ritorna tutti i vertici ed i collegamenti che partono dal RID #8:0 (Napoli) e si ferma quando viene raggiunta la profondità (depth) di 2. L’operatore WHERE serve ad eliminare i link, a mantenere solo i vertici e ad escludere il nodo radice, cioè quello di partenza. Figura 2.34: SELECT su Graph-DB Conclusioni Nonostante la tecnologia NoSQL non abbia alla base delle linee guida che ne riescano ad identificare e differenziare gli aspetti fondamentali, abbiamo visto come tale modello si sia nel corso degli anni sviluppato molto velocemente. Ad oggi sono moltissime (più di 220) le tipologie e le applicazioni in circolazione (in gran parte Open Source) che si distinguono tra loro per tantissime caratteristiche peculiari. Ciò che però le accomuna tutte è il fatto di poter essere una valida alternativa a quello che è stato fino ad ora il modello più utilizzato in tutti gli scenari applicativi, ovvero il modello relazionale. Per avere un quadro della situazione più chiaro, sono state messe in evidenza tutte le lacune di tale modello, come la scarsa disponibilità e l’inflessibilità dei suoi schemi. Fatto ciò abbiamo apprezzato in che modo i database NoSQL vogliano risolvere i problemi che vengono riscontrati con i relazionali, enfatizzando le caratteristiche più richieste nei casi d’uso moderni come velocità, scalabilità e alta disponibilità. Successivamente è stata posta l’attenzione sui modelli di sviluppo che stanno alla base di tali strutture: ACID e BASE. Di tali modelli ne sono state esposte le caratteristiche, evidenziandone le differenze. E’ stata poi fornita una breve spiegazione del perché i database NoSQL non possano essere la soluzione di tutti i problemi applicativi che intercorrono con i database RDBMS e abbiamo quindi differenziato, per entrambe le tecnologie, i casi d’uso in cui sarebbe più opportuno utilizzarli. Infine abbiamo presentato un piccolo esempio attraverso OrientDB, un database NoSQL di tipo document-graph-key/value che ci ha permesso di mostrare, in maniera pratica, alcuni dei vari aspetti positivi di tali database (in particolare dei document e dei graph) quali la flessibilità sugli schemi, l’introduzione di campi particolari come gli embedded-document e la capacità di poter lavorare con dati non strutturati ; parametri che oggigiorno prevalgono sul mercato. Bibliografia [1] G.Vaish, Getting Started with NoSQL, Packt Publishing, Birmingham, 2013. [2] A.Chianese, V.Moscato, A.Picariello, L.Sansone, Basi di dati per la gestione dell’informazione, McGraw-Hill, Milano, 2010. [3] C.Tesoriero, Getting Started with OrientDB, Pack Publishing, Birmingham, 2013. [4] The Apache Software Foundation, URL: https://www.apache. org/ [5] Database NoSQL, URL: http://nosql-database.org/ [6] Guida OrientDB, guida-orientdb/ URL: 41 http://www.html.it/guide/