LabDB - MADB

66

Transcript of LabDB - MADB

Page 1: LabDB - MADB

LabDB - MADB

Appunti delle lezioni diPaolo Alfano

Page 2: LabDB - MADB

Note LegaliLaboratorio avanzato di basi di dati - Modelli avanzati e architetture di basi didatiè un'opera distribuita con Licenza Creative CommonsAttribuzione - Non commerciale - Condividi allo stesso modo 3.0 Italia.Per visionare una copia completa della licenza, visita:http://creativecommons.org/licenses/by-nc-sa/3.0/it/legalcodePer sapere che diritti hai su quest'opera, visita:http://creativecommons.org/licenses/by-nc-sa/3.0/it/deed.it

Liberatoria, aggiornamenti, segnalazione errori:Quest'opera viene pubblicata in formato elettronico senza alcuna garanzia dicorrettezza del suo contenuto. Il documento, nella sua interezza, è opera diPaolo Didier Alfanoe viene mantenuto e aggiornato dallo stesso, a cui possono essere inviate even-tuali segnalazioni all'indirizzo [email protected] aggiornamento: 22 giugno 2018

2

Page 3: LabDB - MADB

Indice

1 Architettura di un database 6

1.1 Architettura �sica di un database . . . . . . . . . . . . . . . . . . 61.2 Startup e shutdown . . . . . . . . . . . . . . . . . . . . . . . . . . 81.3 Transazioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91.4 Architettura logica . . . . . . . . . . . . . . . . . . . . . . . . . . 101.5 Data dictionary . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

2 Backup e Recovery 15

2.1 Backup �sici . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162.2 Recovery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172.3 Recovery manager . . . . . . . . . . . . . . . . . . . . . . . . . . 192.4 Backup logici: import/export . . . . . . . . . . . . . . . . . . . . 202.5 SQL loader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

3 Data warehousing 22

3.1 Viste materializzate . . . . . . . . . . . . . . . . . . . . . . . . . 233.2 Partizionamento . . . . . . . . . . . . . . . . . . . . . . . . . . . 263.3 Indici bitmap e function based . . . . . . . . . . . . . . . . . . . 27

4 Prestazioni e tuning 29

4.1 Transparent Network Substrate, DB Link e 2PC . . . . . . . . . 294.2 Tuning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

5 Oracle Context 34

5.1 Large Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345.2 Oracle Context . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

6 Utilità Oracle 36

6.1 In memory database . . . . . . . . . . . . . . . . . . . . . . . . . 366.2 NO-SQL database . . . . . . . . . . . . . . . . . . . . . . . . . . 376.3 Multitenant database . . . . . . . . . . . . . . . . . . . . . . . . . 386.4 Scheduler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

7 Introduzione ai NO-SQL database 41

7.1 Modelli aggregati . . . . . . . . . . . . . . . . . . . . . . . . . . . 417.2 Materialised views . . . . . . . . . . . . . . . . . . . . . . . . . . 45

8 Modelli di distribuzione dei dati 45

8.1 Quattro modelli di distribuzione . . . . . . . . . . . . . . . . . . 458.2 CAP theorem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 478.3 Quorum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 498.4 Version stamp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 498.5 Paradigma map-reduce . . . . . . . . . . . . . . . . . . . . . . . . 508.6 Persistenza poliglotta . . . . . . . . . . . . . . . . . . . . . . . . . 52

3

Page 4: LabDB - MADB

9 Database chiave-valore: Riak 53

9.1 Elementi generali . . . . . . . . . . . . . . . . . . . . . . . . . . . 539.2 Memorizzazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

10 Database a colonne: HBase 57

11 Database a documenti: MongoDB 59

12 Database chiave-valore: Redis 64

13 Database a grafo: Neo4J 64

Page 5: LabDB - MADB

Parte Prima:

Database Oracle

Page 6: LabDB - MADB

26 / 02 /2018

1 Architettura di un database

Nel seguito vedremo come è strutturato un database relazionale basandoci sullelinee guida sviluppate da Oracle. Dunque vediamo una breve storia dell'archi-tettura sviluppata da questa azienda.

Il nome Oracle emerge con la versione 6 rilasciata nel 1988. Nel 1998 vienerilasciata la versione 8i dedicata alla gestione di database tramite internet. Adoggi viene usata la versione 12c sviluppata per poter gestire anche il cloud. Laversione attuale presenta molti pregi ma ha il problema di non essere proce-durale, ovvero l'ordine delle istruzioni del programma non è particolarmenteimportante. Per questo motivo negli anni successivi vengono sviluppate delleversioni embedded di SQL all'interno di altri linguaggi come il C o il COBOL e ilcodice SQL viene "tradotto" in comandi del linguaggio ospite. Questo costrin-geva i clienti a comprare dei compilatori di terze parti ed è per questo che inseguito Oracle propone un proprio linguaggio usato ancora oggi detto PL/SQL.Intorno a questo linguaggio si sviluppano una serie di strumenti detti develop-ment tool per fornire alcune funzionalità aggiuntive. In seguito vengono anchesviluppati degli strumenti di data warehousing per permettere a �gure menocompetenti come i manager di avere un facile accesso ai dati. L'ultimo sviluppoè stato nella gestione dei big data, ancora in lavorazione.Ad oggi esistono diverse versioni del software Oracle che comunque hanno ununico motore relazionale: Express che è free, la versione Standard che coprela maggior parte delle funzionalità e la Enterprise a cui possiamo associarefunzionalità aggiuntive. Esiste anche una versione lite che veniva usata comeappendice per le versioni standard o enterprise ma che ad oggi non è più tantodi�usa a causa della crescita computazionale dei dispositivi che spesso possonocomunque far girare una versione Express o Standard

1.1 Architettura �sica di un database

Abbiamo fondamentalmente tre componenti �siche per un database, lamemoria,i �les e i processi. Memoria e processi costituiscono un'istanza Oracle mentre iprocessi e i �les costituiscono il database. Andiamo a studiare ognuna di questecomponenti più nel dettaglio facendo riferimento alla Figura 1

1. Memoria: abbiamo un'area di memoria condivisa detta SGA(Shared globalarea) suddivisa in più parti. Una di queste è la shared pool che a sua voltaè formata da

- library cache: contiene il codice

- data dictionary cache: contiene una libreria di dati relativa allastruttura del database(numero degli utenti. . .)

6

Page 7: LabDB - MADB

Figura 1: Architettura di un database

Un'altra area è quella del data bu�er cache che contiene i dati relativi alletransazioni che avvengono sul database. Infatti quest'area occupa circa il90%-95% della memoria.In�ne abbiamo il redo-log bu�er, un piccolo �le che contiene il log delleultime operazioni e�ettuate

2. Files: a questa categoria appartengono i �les dei dati e i �le tempora-nei(�le che vengono usati come area di swap da alcuni processi). Abbiamopoi un unico �le di controllo di cui viene tenuta una copia che indica lalocazione di tutti gli altri �le. Abbiamo in�ne i redo log �les che servonoper stabilizzare su disco il redo log bu�er. Solitamente quando i redo log�les si riempiono viene attivato un processo dedicato che va ad archiviarei �le di log. Abbiamo poi il �le dei parametri che viene creato con valoridi default ma che può anche essere speci�cato per personalizzare alcuniaspetti del database come la dimensione dell'area di memoria o altro an-cora. Abbiamo in�ne un �le delle password che non è relativo a passworddei dati bensì contiene delle password utilizzate per e�ettuare alcune chia-mate del sistema operativo.Esiste anche un �le di alert e dei �les di trace che contengono le informa-zioni relative ad eventuali anomalie veri�catesi nel sistema.

3. Processi: legano le due componenti precedentemente descritte. I processipiù noti sono: il db writer che porta i dati dalla memoria al disco e vi-ceversa. Abbiamo poi un log writer che si occupa della scrittura del logdalla memoria ai �le. Esistono anche due processi detti system monitor e

7

Page 8: LabDB - MADB

process monitor che si occupano rispettivamente dell'allineamento dei datie dei processi. Esiste in�ne un processo di archiviazione che va a renderepersistenti le modi�che al log.

Cosa succede quando un utente cerca di connettersi al database da un terminaleremoto?Inizialmente viene creato uno user process che si mette in comunicazione conun server process. Il compito di quest'ultimo è di prendere i dati dai �le eportarli nella data bu�er cache. In questo modo l'utente potrà modi�care inmodo asincrono i dati nella bu�er cache e tali modi�che vengono poi riportatesui �le e sul log dai rispettivi processi(db writer e log writer).Ogni volta che viene creato un server process gli viene associata anche un'areadi memoria personale detta PGA in cui vengono salvati i risultati temporanei.Se l'area di memoria non è su�ciente, vengono allora usati i �le temporanei suldisco.

1.2 Startup e shutdown

Ora che sappiamo quale è la struttura di un database andiamo ad analizzare duefasi delicate, l'avvio e lo spegnimento. Cominciamo con l'avvio. Supponendo dicominciare con un sistema completamente spento abbiamo tre fasi

1. Nomount: in questa fase viene analizzato il �le di inizializzazione e vie-ne allocata la memoria. Inoltre viene recuperata la locazione del �le dicontrollo

2. Mount: viene recuperato il �le di controllo che mi fornisce la posizione ditutti gli altri �le

3. Open: vengono aperti tutti i �le necessari. A questo punto il database èpronto

Ad ogni modo la fase di startup può anche essere eseguita in modalità restrictche permette solo ad alcune persone(gli amministratori ad esempio) di eseguirecerte operazioni.

Per quanto riguarda lo shutdown invece abbiamo quattro possibili modi pere�ettuarlo: abort, immediate, transactional, normal. Confrontiamoli in Tabel-la 1

Tipo Abort Imm. Tran. Norm.Permette nuove connessioni no no no no

Attende terminazione sessione corrente no no no sìAttende terminazione transaz. corrente no no sì sì

Forza checkpoint, chiude i �les no sì sì sì

Tabella 1: Confronto fra i vari tipi di shutdown

8

Page 9: LabDB - MADB

Lo shutdown abort è sempre sconsigliato poiché lascia molte situazioni ir-risolte e questo viene pesantemente pagato allo startup successivo in cui nonpotremo ricostruire alcune cose.La modalità normal invece termina in modo �n troppo pulito. Infatti se ancheun solo utente dimentica di chiudere la propria sessione, lo shutdown non puòessere e�ettuato.Per questi motivi le due modalità più utilizzate sono le due rimanenti, ovveroimmediate and transactional.

1.3 Transazioni

Cominciamo ad introdurre le transazioni.Uno stato viene detto consistente se i suoi dati rispettano tutti gli integrityconstraint del database.Allora una transazione è un insieme di operazioni che viene avviato su uno sta-to consistente S0. A partire da questo stato eseguo diverse manipolazioni e -senon vi sono problemi- raggiungo uno stato consistente S1 di cui potrò eseguireil commit. Se però incorro in qualche problema termino in uno stato consistentenon accettabile da cui dovrò eseguire l'operazione di rollback

27 / 02 /2018

Andiamo ad analizzare nel dettaglio l'esecuzione di uno statement SQL. Ri-cordando che le operazioni più comuni sono di cancellazione, inserimento, ag-giornamento e selezione possiamo andare ad individuare diverse fasi:

1. Parse: in questa fase abbiamo alcune sotto fasi. Una di validazione dellasintassi eseguita sullo statement a cui segue una fase di validazione dellaterminologia in cui controlliamo la correttezza dei riferimenti. In seguitoabbiamo una terza fase di validazione dell'utente con cui andiamo a veri�-care se l'utente possieda i permessi necessari per eseguire lo statement. Leultime due fasi appena elencate vanno ad usare il data dictionary. Nellafase di esecuzione del piano andiamo a valutare quali siano i piani possibilie andiamo a selezionare il migliore. Queste scelte vengono memorizzatenella library cache dell'area di memoria SGA

2. Bind delle variabili e delle costanti

3. Fase opzionale dipendente dal tipo di statement: se abbiamo un'operazionedi selezione abbiamo e�ettivamente un risultato di ritorno. In questocaso eseguiamo la fase di describe che si occupa di dimensionare l'area dimemoria per contenere il risultato. Per ogni altro tipo di statement questafase non viene eseguita

4. Execute: andiamo a recuperare il primo dato impostando un cursore,ovvero una risorsa che scorre nell'insieme dei dati per selezionarli

9

Page 10: LabDB - MADB

Figura 2: Evoluzione di uno statement SQL

5. Fase opzionale dipendente dal tipo di statement: se abbiamo una querydobbiamo e�ettuare il fetch del dato successivo

L'intero procedimento è riportato in Figura 2Un problema che si presenta con tutte le transazione è il seguente: quando

eseguo una transazione vorrei che tutti gli altri processi vedano il dato nel suostato originale �no a quando la mia transazione non è terminata. Per ovviare aquesto problema �no all'operazione di commit viene creata una copia del datooriginale. Questa copia ha due scopi: il primo è quello di permettere agli altriprocessi la lettura del dato originale. Il secondo è di permettere l'esecuzione diun'operazione di rollback nel caso si veri�chino problemi.Notiamo in�ne che il concetto di rollback e di redo log sono nettamente diversifra loro:

- rollback: politica utilizzata per disfare qualcosa in senso "decostruttivo"di una transazione

- redo log: politica utilizzata per ripercorre quanto accaduto in modo "co-struttivo" di una serie di transazioni avvenute

1.4 Architettura logica

Mostriamo lo schema completo dell'architettura logica in Figura 3Per comprenderla partiamo dal database e seguiamo il "ramo" verso destra.

Un database è logicamente organizzato in tablespace che sono distribuite su deidata�le. Questi data�le sono distribuiti su dei blocchi di memoria detti oracle

10

Page 11: LabDB - MADB

Figura 3: Schema completo dell'architettura logica

block che a loro volta sono dei multipli dei blocchi di memoria del sistema ope-rativo.Consideriamo invece il "ramo" che si sviluppa verso il basso a partire dal data-base. Ad ogni database sono associati sempre un certo numero di "utenti" dettiowner. Questi owner sono sempre almeno due:

- Sys: è proprietario del data dictionary e di altri elementi di gestione deldatabase e può fare fondamentalmente quello che vuole.

- System: non è proprietario come l'utente Sys ma ha fondamentalmentegli stessi poteri di Sys.

L'ordinaria amministrazione viene svolta da System. In alcuni casi eccezionaliinterviene Sys.Ad ogni utente viene poi associato uno schema che contiene tutte le informazio-ni relative agli oggetti di quell'utente. Infatti ad ogni schema sono poi associatitutta una serie di segments che sono gli oggetti veri e propri(tabelle, indici, lar-ge binary objects(LOB). . .). I segments sono poi organizzati negli extent, unaporzione �sica di spazio dedicata all'oggetto.I due rami che abbiamo appena percorso sono però collegati perché infatti ognisegment(oggetto) appartiene necessariamente ad una certa tablespace. Inoltrepiù di recente è stato introdotto il concetto di partizione per distribuire i datiin tante componenti più gestibili.

Sebbene l'architettura logica teorica sia questa, esistono delle linee guida piùpratiche per la creazione di architetture. La Oracle propone la Optimal FlexibleArchitecture(OFA).In questo caso i dati vengono distribuiti su quattro supporti(dischi) diversi:

- usr1: contiene �le di controllo o di servizio relativi ad Oracle come i �ledi alert, quelli di archive e quindi non contiene dati

11

Page 12: LabDB - MADB

Figura 4: Struttura di un blocco

- usr2: contiene la tablespace system relativa agli indici e alle viste del datadictionary

- usr3: contiene dei segmenti di undo e gli indici degli utenti

- usr4: contiene dei meta dati integrativi necessari al funzionamento deldata dictionary. Contiene inoltre le tabelle dei dati degli utenti

Se viene implementata questa architettura abbiamo sei diverse tablespace: SY-STEM per il data dictionary, TOOLS per le applicazioni, DATA per i dati,INDEX per gli indici, RBS per i segmenti di rollback e in�ne TEMP per i seg-menti temporanei.

Com'è strutturato invece un blocco di memoria? Lo mostriamo in Figura 4L'area indicata in verde è di servizio e mantiene all'interno tutte le compo-

nenti necessarie per legare il blocco al data�le. Dopo abbiamo un'area liberadi cui parliamo fra poco e in�ne un'area in violetto dedicata agli n record delblocco. Quest'ultima contiene i record che a loro volta dedicano una porzionedi spazio a dati di servizio del record seguita da un'area per speci�care la lun-ghezza del dato e in�ne il vero e proprio dato.

Giusti�chiamo quanto detto �nora supponendo di voler creare un oggetto, ov-vero una tabella. Questo possiamo farlo speci�cando il comando CREATETABLE. Oltre ai soliti campi relativi alla tabella che vogliamo creare, possiamoandare a speci�care qualche campo in più che di solito è speci�cato di defaultma che adesso abbiamo gli strumenti per speci�care manualmente:

• TABLESPACE: possiamo speci�care a quale tablespace associare la nuo-va tabella. Se non è speci�cato viene associata alla tabella di defaultdell'utente

12

Page 13: LabDB - MADB

• STORAGE: speci�ca le caratteristiche di collocamento della tabella. Laprima caratteristica è la initial con cui speci�chiamo la dimensione �-sica del primo extent associato all'oggetto. Se l'initial non è su�cienteper contenere l'oggetto, tramite il campo next possiamo associare ulte-riori extents per contenere l'oggetto. Possiamo speci�care quanti extentsvogliamo avere almeno o al massimo tramite i campi minextents e maxex-tents. In�ne tramite il campo pctincrease possiamo andare a speci�caredi quale percentuale si incrementerà la dimensione del prossimo extentsrispetto al precedente. Ovvero se pctincrease=50 il successivo extent saràpiù grande del 50% più rispetto al precedente.

• PCTFREE: possiamo andare a speci�care la percentuale rimanente oltrela quale un blocco viene considerato pieno ai �ni dell'inserimento. Percomprendere meglio, se PCTFREE = 20, allora quando il blocco è pie-no all'80% non potremo più e�ettuarvi inserimenti. Lo spazio rimanente,indicato in trasparente in Figura 4, ci permette eventualmente di gestirel'estensione o la modi�ca di qualche dato senza dover andare necessaria-mente a prendere un nuovo blocco1 che è un'operazione costosa. Ovvia-mente se sappiamo che i dati sono molto statici tenderemo a settare unPCTFREE basso, magari pari a cinque.

1.5 Data dictionary

Procediamo ad analizzare una componente importante del database, ovvero ildata dictionary. Ha alcune proprietà fondamentali

• Descrive il database e i suoi oggetti

• Contiene le tabelle di sola lettura e le viste

• È posseduto da Sys, ma è collocato nel tablespace di System

• Accedibile tramite una SELECT

• Fornisce informazioni riguardo strutture logiche e �siche, de�nizione e spa-zio di allocazione degli oggetti, integrity constraints, utenti, ruoli, privilegi. . .

Dal data dictionary possiamo accedere a tre tipi di viste: user_tables che for-niscono informazioni riguardo tutte le viste create dall'utente, all_tables cheaggiunge gli oggetti a cui altri utenti mi hanno consentito l'accesso e in�ne ledba_tables che contengono le informazioni riguardo tutte le tabelle presenti neldatabase. Come dice il nome, quest'ultima vista può essere solitamente accedu-ta soltanto dal database administrator. Questa situazione è mostrata in Figura 5

06 / 03 /2018

Come già visto in precedenza, anche il data dictionary viene distribuito nei

1Questa operazione viene detta chaining

13

Page 14: LabDB - MADB

Figura 5: Viste accessibili dal data dictionary

vari extents, segments e tablespace.

Quali sono invece le responsabilità dell'amministratore del database?

- Installare e aggiornare il DBMS relazionale

- Creare e modi�care le strutture e gli oggetti primari

- Piani�care l'archiviazione

- Inserimento e accesso degli utenti

- Stabilire le politiche di backup e recovery, e gestire la sicurezza

- Miglioramenti delle prestazioni: quando abbiamo dei tempi lunghi cer-chiamo di ottimizzare. Questa operazione solitamente viene piani�cataper prevenire il degrado delle prestazioni e non quando abbiamo già unasituazione di crisi

- Consulenza(sviluppo): ricerca delle migliori soluzioni ai problemi

Come viene creato un nuovo database in ambiente Oracle? Solitamente abbiamotre fasi: pre-installation, installation, post installation.

1. Pre-installation:

- Organizare il contenuto del DB: tramite le OFA e le linee guidaspiegate in precedenza studiamo come suddividere i contenuti nelletablespace

- Disegnare la struttura �sica per ridurre la frammentazione dei dischi

- Preparare l'ambiente di sistema operativo tramite variabili d'ambien-te e di kernel

- Personalizzare il �le dei parametri

2. Installation:

14

Page 15: LabDB - MADB

- StartUp NoMount: viene avviato lo StartUp del DB nella fase No-Mount di cui abbiamo parlato in precedenza. Questa fase vieneattraversata una sola volta nella vita del database

- Avvio dello statement SQL di Create DB: di solito questa fase nonviene percepita perché e�ettuata automaticamente tramite l'inter-faccia gra�ca di installazione. In questa fase vengono create diversetablespace e vengono creati gli utenti Sys e System

3. Post-installation:

- Creazione delle strutture metadati: viene creato il dizionario datitramite una serie di �le di script

- Creazione di ulteriori tablespace: ad esempio quelle delle tabelle degliindici degli utenti �nali

- Creazione degli utenti applicativi: vengono creati gli utenti e il DBviene con�gurato per permettergli l'accesso

2 Backup e Recovery

Abbiamo due strategie fondamentali di backup: logico e �sico. Non esiste untipodi backup migliore fra i due e anzi vedremo che la soluzione migliore è usarliin coppia. Vediamo in maggiore dettaglio come possono essere fatti i backup

• Backup logico: sono demandati a dei tool che il DBMS mette a disposizio-ne e permettono di prendere i dati dal DB e potarli sul sistema operativoin un formato logico

• Backup �sico: si divide in alcune sotto-categorie. Infatti possono essere

- A caldo o a freddo: a freddo vuol dire che il DB viene spento e vienefatta una copia di tutte le componenti �siche del DB. A caldo invecevuol dire che con DB operativo viene e�ettuato il backup con alcuneaccortezze ulteriori

- Con RMan o senza: utilizzo dello strumento Recovery Manager, unostrumento messo a disposizione da Oracle

Quali sono gli obiettivi per le strategie di backup e recovery? Proteggereil DB dai vari tipi di fallimenti che possono veri�carsi, ridurre il tempo cheintercorre tra un fallimento e il successivo, decrementare il tempo per gestireuna situazione di fallimento e in�ne minimizzare la perdita di dati ogni voltache si veri�cano fallimenti.Quali sono dunque i tipi di fallimento possibili?

• Statement failure: errore di tipo logico, come una violazione delle integritàreferenziali. Un esempio potrebbe essere l'inserimento di un dato di for-mato sbagliato in una tabella. Questi fallimenti sono di gravità minima,non richiedono l'operazione di recovery.

15

Page 16: LabDB - MADB

Figura 6: Procedimento di archiviazione

• User process failure: può veri�carsi se per un qualche motivo il processoclient smette di rispondere. A questo punto il processo server non sapiù con chi comunicare. Questa situazione non necessita di recovery marichiede che il processo process monitor gestisca la situazione

• User error: si veri�ca quando viene e�ettuato un aggiornamento non con-trollato dei dati. Ad esempio quando viene eliminata per sbaglio una ta-bella. In questo caso serve un recovery dei dati e dunque viene e�ettuatoun backup logico

• Instance failure: dato da un problema hardware sulla CPU o sulla RAMmentre lavoriamo sull'istanza, ovvero sull'insieme dei processi iniziati eallocati. Anche in questo caso la situazione può essere gestita dal processmonitor o dal system monitor

• Media failure: problema �sico su un dispositivo di input/output. Serveper forza una recovery e il backup �sico è quello che ci aiuta in questocaso essendo il problema di natura �sica.

2.1 Backup �sici

Un aspetto che è importante sottolineare subito è che nei backup a caldo èfondamentale che sia attiva la modalità archive. Infatti come vedremo sonoproprio i �le archiviati che ci permettono di gestire le situazione di media failure.Solitamente il procedimento di archiviazione procede come segue: supponiamodi avere due online redo log �le e di avere due copie per entrambi. Quandoil �le in uso è saturo cominciamo a salvare le successive operazione nell'altro.Nel frattempo il processo di archiviazione va a salvare il �le saturo in archivio.Questa operazione viene mostrata in Figura 6

Se ad un certo punto la modalità di archiviazione non è attiva, dobbiamoeseguire lo shutdown, e�ettuare una startup mount, eseguire una alter database

16

Page 17: LabDB - MADB

archivelog e una alter database open. In�ne eseguire uno shutdown ed e�ettuareun backup completo del database.Ovviamente le informazioni riguardo l'archive log sono ottenibili mediante ildata dictionary. Infatti possiamo ottenere il log stesso, una cronologia i processidi archiviazioni avviati. . .

Vediamo invece come vengono e�ettivamente eseguite le procedure di backup�sico:

• A freddo: è più facile da gestire, dobbiamo e�ettuare uno shutdown, pren-dere tutti i �le da salvare dunque i dati, i �le di controllo, di redo log, dellepassword, dei parametri e andare a salvarli su un supporto online. Dopopossiamo e�ettuare una startup.I vantaggi di questo metodo è freddo sono i seguenti: è concettualmentesemplice, è facile eseguire e richiede poca interazione tra le parti. Pur-troppo lo svantaggio è che in ambito aziendale solitamente un databasenon può permettersi di e�ettuare lo shutdown ed essere indisponibile peril tempo del backup, che può anche essere di qualche ora.

• A caldo: certamente senza dover fare lo shutdown possiamo andare a sal-vare tutte quelle componenti che non sono toccate mentre il database èattivo, come i �le di controllo, quello dei parametri, quello delle passworde i redo log archiviati.Il problema si presenta quando dobbiamo salvare i �le dati che potrebberoessere soggetti a modi�che da parte degli utenti. Quando viene eseguitolo statement di begin backup tutte le transazioni cominciano a scrivere leloro modi�che su �le temporanei e viene avviato il procedimento di bac-kup. Tramite lo statement end backup il procedimento �nisce e gli utentiriprendono a scrivere direttamente sul database.I vantaggi in questo caso sono che il database è sempre disponibile edunque supporta operazioni di business continuamente

2.2 Recovery

Andiamo invece a vedere come viene gestito un media failure. Per comprenderel'intero procedimento dobbiamo illustrare che ad ogni �le di redo log è associatoun numero detto log �le number. Ad esempio in Figura 6 i due �le di redolog hanno un log �le number pari a 52 e 53. Quando un �le di redo log èsaturo viene avviato(come già detto) il processo di archive e il log �le numberviene incrementato al primo valore disponibile. Supponiamo allora di avere lasituazione mostrata in Figura 7.

Supponiamo che vengano eseguiti i seguenti passi

1. Viene fatto un backup a caldo del database. Viene quindi salvato che ilpiù alto log �le number è 144

2. Un processo utente richiede dei dati

17

Page 18: LabDB - MADB

Figura 7: Procedimento di recovery

3. I dati vengono prelevati da un blocco di �le di dati e forniti al serverprocess

4. Il data bu�er e il redolog bu�er nella SGA richiedono rispettivamente aiprocesso DBWn e LGWR di andare a salvare le modi�che rispettivamentesul �le dati e sul redo log

5. Vengono salvate le modi�che sul redo log �le

6. Vengono salvate le modi�che su uno dei data �le

7. Il redo log �le 1 avente log �le number 144 è saturo. Viene avviato ilprocesso di archiviazione e il suo log �le number diventa 146 perché 145era già preso dal redo log �le 2.

8. A seguito di ulteriori richieste vengono modi�cati ancora i �le di dati

9. Dunque allo stesso modo queste richieste vanno a modi�care il redo log�le number 2 avente log �le number pari a 145.

10. Anche il redo log �le number 2 è saturo. Viene avviato il processo diarchiviazione e il suo log �le number viene portato a 147 poiché il valore146 era già stato assegnato al redo log �le 1

11. Si veri�ca un media failure sul data �le 2

Come possiamo gestire questa situazione di fallimento? In questo caso dobbiamoseguire i seguenti passi

18

Page 19: LabDB - MADB

1. Eseguire lo shutdown del database

2. Eseguire il restore del data �le 2 utilizzando il redo log �le avente log �lenumber 144 che avevamo salvato con il backup

3. Eseguire una startup mount

4. Ricostruire il data �le 2 usando il redo log �le avente log �le number 144

5. Ricostruire il data �le 2 usando il redo log �le avente log �le number 145salvato nei �le archiviati

6. Ricostruire le ultime transazioni del data �le 2 usando il redo log �le aventelog �le number 146

7. Eseguire una alter database open

Solitamente di tutti i �le di redo log viene mantenuta una copia per evitare chenon si possa ricostruire un data �le a seguito di un media failure.Come abbiamo visto �nora, ad ogni �le di log è associato un log �le number checi permette di ricostruire l'ordine dei �le di log in caso di un qualche malfun-zionamento.Per raggiungere un livello di maggiore granularità possiamo anche utilizzare unSystem Change Number(SCN).Questo SCN è di fatto un timestamp incrementale che caratterizza una versionecommittata stabile e sicura del database ad un certo timestamp. Questo valoreviene associato ad ogni operazione scritta sul redo log. In conclusione un redolog �le possiede solitamente tre attributi: il log �le number, un Low SCN num-ber che indica il più basso SCN e un high SCN number che indica il più altoSCN. Questi due ultimi attributi servono per eventuali ricerche.

2.3 Recovery manager

Il Recovery manager (RMAN) è uno strumento di Oracle che può essere utiliz-zato per il backup, le operazioni di restore e recovery. Permette di e�ettuare ibackup sia su �le online che su dischi o altri supporti

19 / 03 /2018

Tutte queste operazioni vengono e�ettuate da RMAN andando ad avviare unaserie di processi server. Ad esempio uno si occupa di interagire con il database ede�ettuare il backup. Un altro si occupa di salvare il recovery catalog database.Ad ogni modo quest'ultima operazione è opzionale visto che il recovery catalogdatabase va a memorizzare gli stessi metadati contenuti nel �le di controllo.Quali sono i vantaggi di utilizzare RMAN rispetto ad altri metodi?

- Può lavorare a livello di singolo blocco e questo ci permette di interferirepoco con il lavoro del database

19

Page 20: LabDB - MADB

- Cattura informazioni sui blocchi corrotti nel database e negli archived �le

- È con�gurabile in base ai dispositivi di input/output che stiamo utilizzan-do

- Permette di eseguire backup incrementali anche con elementi di terze parti

- I comandi da usare sono molto semplici. Ad esempio, per e�ettuareil backup del database e del log possiamo eseguire il comando "BAC-KUP DATABASE PLUS ARCHIVELOG" che e�ettivamente è di facileinterpretazione

2.4 Backup logici: import/export

Un problema dei metodi di backup �sici è che spesso sono troppo laboriosi. Perquesto motivo vengono usate anche delle funzioni di import ed export. Questeutility permettono di

- E�ettuare un backup prima che un dato venga rimosso dal database

- Salvare alcune de�nizioni di tabelle e altri elementi per proteggerli daproblemi futuri

- A�rontare la movimentazione di dati tra piattaforme diverse tra loro, ma-gari aventi una diversa versione di Oracle o addirittura un diverso sistemaoperativo

Dalla versione 10g di Oracle database sono stati introdotti i data pump impor-t/export.Vediamoli in maggiore dettaglio:

• Export data pump: si occupa di esportare i dati dai data �les ai �le delsistema operativo. Abbiamo di fatto tre modi per fare l'export. La primamodalità detta table va ad esportare alcune tabelle, o indici. . .Con la seconda modalità detta Schema andiamo invece ad esportare tuttigli oggetti posseduti da un utente.Invece con la terza modalità detta Full database andiamo ad esportare l'in-tero database ad eccezione degli oggetti di SYS. Questi ultimi non vengonoesportati perché ci aspettiamo che vengano costruiti ex novo al momentodell'importazione. Infatti i valori dei �le di SYS potrebbero essere validiadesso ma non nel futuro.Ad ogni modo l'operazione di export possiede molti parametri per perso-nalizzare l'intero processo.In questo processo di esportazione ricoprono un ruolo importante le direc-tory. Solitamente prima di andare ad e�ettuare l'import/export andiamoad eseguire un comando che crea una directory come segue:

SQL> CREATE DIRECTORY mydir AS '/usr/apps/expdpfiles';

20

Page 21: LabDB - MADB

Le directory sono degli oggetti Oracle che si occupano di gestire la map-patura tra livello logico e livello �sico. Nel comando che abbiamo datopoc'anzi il livello logico è contenuto nella parola mydir, mentre il livello�sico è speci�cato nella directory '/usr/apps/expdp�les'

• Import data pump: di fatto è un costruttore di codice SQL che esegue dellecreate, e delle insert. Quando andiamo ad eseguire una import, vengonoe�ettuati i seguenti passi:

1. Vengono de�niti i tipi che verranno implementati

2. Vengono de�nite le tabelle che verranno implementate

3. Introduciamo i dati

4. Costruiamo l'indice quando abbiamo inserito tutti i dati. Questo cigarantisce di avere degli indici meglio organizzati

5. Veri�chiamo le integrità referenziali

6. Costruiamo le views

7. Costruiamo le procedure e i trigger(che vedremo in seguito)

8. Creiamo le bitmap e gli indici funzionali

2.5 SQL loader

Un'altra utility ampiamente utilizzata e che ha raggiunto una propria stabilitàa partire dalle ultime versioni è l'SQL loader. Parte da un insieme di �le eproduce in output gli oggetti tabella popolati dai dati contenuti nei �le. Questoprocedimento complesso viene eseguito in più passi, lo mostriamo in Figura 8

Il primo passo consiste nel �eld processing. Questo ci permette di capire conquali dati avremo a che fare. Nel caso in cui vi siano alcuni record che nonrispettano la descrizione, li inseriamo in un �le dedicato detto bad �le. Ad ognirecord nel bad �le è anche associata una spiegazione di come mai quel record siastato inserito nel bad �le. L'idea è che dopo questa prima fase possiamo andarea controllare il contenuto del bad �le, andare a correggere gli errori e rieseguirela prima fase utilizzando come input il bad �le.La seconda fase viene detta record selection in cui andiamo a selezionare i datiche ci servono. Quelli che eventualmente non ci servono li andiamo ad inserirein un �le dedicato detto discard �le.In seguito andiamo a veri�care le integrità referenziali per i dati che abbiamoconservato. Nel caso in cui non le rispettino li andiamo ad inserire nel bad �le.È a questo punto che i �le vengono e�ettivamente salvati.Ad ogni modo anche questa operazione può essere facilmente personalizzatagrazie ai molti parametri disponibili:

- Userid: per speci�care utente e password

- Control, log, bad, data, discard: per speci�care i nomi dei �le elencati

- Discardmax: speci�ca il numero di discard tollerabile

21

Page 22: LabDB - MADB

Figura 8: Procedimento di caricamento mediante SQL loader

- Skip, load: per speci�care se saltare alcune parti e quali record caricare

- Errors: speci�ca il massimo numero di elementi tollerabili nel bad �leprima di fermare il procedimento di caricamento, di default è 50

- Silent: sopprime i messaggi nel corso dell'esecuzione

- Rows: numero massimo di inserimenti da eseguire in contemporanea, dideafult è 64

- Direct: permette l'inserimento diretto in memoria senza passare dal co-mando SQL insert che sarebbe molto più costoso. Possiamo farlo perchésiamo a conoscenza di come sono strutturati i blocchi. Questo inserimentomanuale è molto più veloce ma anche molto più rischioso poiché privo deicontrolli dell'SQL

Una componente che a�anca il loader è la external table. Questo tipo di tabella,introdotto con la versione 9 è un particolare tipo di tabella che può solo essereletta. L'external table viene percepita come una qualunque altra tabella quandoinvece giace su un �le esterno. Visto che tale tabella può solo essere letta, allorase abbiamo bisogno di indici aggiuntivi o abbiamo altre necessità è bene fareuso soltanto del loader.

3 Data warehousing

Fino ad ora abbiamo visto come si possano usare i database e gli strumenti mes-si a disposizione da Oracle per gestire i normali processi transazionali. Questo

22

Page 23: LabDB - MADB

scenario "classico" prende il nome di online transaction processing(OLTP).Esiste un secondo approccio che viene usato maggiormente in ambito manage-riale per il supporto alle decisioni. Questo approccio viene detto Online AnalysisProcessing(OLAP) e serve quando vogliamo ricavare delle informazioni statisti-che relative ad un lungo periodo di tempo.È facile comprendere che le necessità di OLTP e OLAP sono molto diverse fraloro. Di�cilmente con l'OLTP andremo a recuperare informazioni vecchie dianni, mentre nel caso dell'OLAP questo è possibile perché la statistica vienefatta su periodi di tempo molto più lunghi.Per questi motivi emerge l'esigenza di avere un altro tipo di database che strut-turalmente non ha nulla di diverso da un database normale, ma il cui scopo èquello di accumulare dati relativamente alle transazioni di un periodo passatomolto lungo. Questo secondo tipo di database, viene detto data warehouse.Solitamente le query dell'OLAP sono complesse e vengono eseguite quando ilcarico di lavoro del database è ridotto, magari di notte.Ad ogni modo vediamo quali devono essere le principali caratteristiche di unambiente di data warehousing: separazione, ovvero deve separare nettamente lefunzionalità di OLAP da quelle di OLTP. Inoltre anche estendibilità, sicurezzae amministrabilità.Vediamo inoltre a livello pratico quali sono le di�erenze tra l'ambiente OLTP eOLAP. Ne abbiamo diverse:

• Indici: gli indici usati nell'OLTP sono pochi e ben precisi. Nel casodell'OLAP invece sono molti per soddisfare le richieste dei manager

• Join: nell'OLTP ne vengono fatti molti mentre nell'ambito OLAP no

• Dati duplicati: solitamente nell'ambito OLTP i dati sono normalizzatimentre nell'ambito OLAP sono denormalizzati

• Dati derivati e aggregati: nell'ambito OLTP sono rari, nell'ambito OLAPsono molto comuni

20 / 03 /2018

Quali sono gli strumenti che possiamo utilizzare nell'ambito del data warehou-sing? Ne abbiamo diversi: le tabelle esterne di cui abbiamo già parlato, le vistematerializzate, le tabelle partizionate, quelle organizzate ad indice e gli indicifunction based. . .

3.1 Viste materializzate

Cominciamo a parlare delle viste materializzate2. Sappiamo che una vista difatto è il risultato prodotto da un query. Allora una vista materializzata diventautile quando dobbiamo fare dei campionamenti statistici molto spesso. Infattila vista materializzata è il risultato di una certa query che dobbiamo mantenere

2In certi ambiti vengono anche dette snapshot

23

Page 24: LabDB - MADB

in memoria perché potrebbe essere richiesta spesso in futuro.Di fatto esistono due modi di utilizzare le viste materializzate

1. Mantenerle in memoria e andare a restituirle esplicitamente quando ser-vono

2. Vengono utilizzate in modo "implicito" dal database con l'operazione diquery rewrite che va ad inserire in modo implicito il risultato al posto diquery o sottoquery

Usare le viste materializzate porta tutta una serie di vantaggi:

- Accesso veloce nel caso di operazioni di join complesse

- Sono trasparenti all'utente �nale

Ovviamente portano anche alcuni svantaggi:

- Maggior spazio occupato, che comunque al giorno d'oggi non è particolar-mente un problema

- Costo di mantenimento della vista materializzata

Per creare le viste materializzate, prima diamo il comando di creazione, in se-guito andiamo a speci�care i campi "initial", "next". . . di cui avevamo parlatonella sottosezione 1.4.Dopo possiamo anche speci�care quando la vista deve essere creata e ogni quantodobbiamo aggiornarla. L'ultima e importante caratteristica è "come" dobbiamoaggiornarla. Abbiamo quattro modi diversi di farlo:

• Never: signi�cato ovvio. Non la aggiorniamo mai

• Complete: va a ripulire l'intera vista e fa ripartire la query senza tenere diconto delle informazioni precedenti. Il pregio è che è sempre applicabile.Il difetto è che non è particolarmente e�ciente come metodo

• Fast: è incrementale perché usa le informazioni raccolte in precedenza mapuò essere usata solo a due speci�che condizioni: esiste lato master unLog e se il Log esiste da un tempo utile a supportare un nuovo refresh

• Force: questo ultimo modo, che solitamente è sconsigliato va a veri�carese può eseguire la fast, altrimenti esegue la complete

Un ulteriore aspetto che possiamo speci�care è il for-update. Con questo coman-do andiamo a modi�care la vista materializzata in base a una nostra previsione.Questo tipo di comando può essere utile negli ambiti di simulazione o di borsa,in cui vogliamo prevedere come cambieranno i valori nel futuro.A livello �sico la vista materializzata coinvolge tutte le componenti mostrate inFigura 9.

24

Page 25: LabDB - MADB

Figura 9: Parti coinvolte dalla vista materializzata

Figura 10: Parti coinvolte dalla vista materializzata con for-update

Notiamo che il trigger scatta dopo che un dato viene aggiornato. In questomodo, ogni modi�ca e�ettuata viene trascritta sul log. Di fatto la vista ma-terializzata viene ottenuta andando ad incrociare i dati contenuti nella mastertable e nel log.Se invece abbiamo utilizzato l'approccio for-update, dobbiamo considerare qual-che componente in più. La struttura è mostrata in Figura 10.

25

Page 26: LabDB - MADB

In questo caso abbiamo bisogno di un trigger aggiuntivo che segua le modi-�che sul log per capire quando vengono toccati i dati che avevamo modi�catotramite la nostra "simulazione". In tal modo possiamo andare a disfare lemodi�che.

3.2 Partizionamento

Quando parliamo di partizionamento ci riferiamo a un partizionamento orizzon-tale. Ovvero andiamo a dividere righe della stessa tabella su macchine diverse.In precedenza, avevamo già introdotto il partizionamento e avevamo detto che,come mostrato in Figura 3 andiamo ad introdurre una relazione molti a moltitra tablespace e segmenti.Cerchiamo di vedere in quanti modi possiamo fare partizionamento:

• Partizionamento per range: la forma di partizionamento più usata quandoabbiamo a disposizione un attributo numerico. Ogni partizione possiedeun valore "value less than" che indica il limite superiore della partizionesull'attributo.

• Partizionamento per liste: utilizzato quando abbiamo dei valori discretiche non hanno una relazione matematica tette fra di loro. Un esempiopotrebbero essere le regioni di Italia. Più spesso questo secondo metodoviene utilizzato come criterio di partizionamento nel partizionamento ditipo composto.

• Partizionamento hash: nel momento in cui non abbiamo alcun criteriopreciso per speci�care le partizioni, andiamo ad utilizzare una partizionebasata su hash. Prendiamo il valore dell'attributo scelto, ne calcoliamol'hash e andiamo a inserire i dati nelle partizioni corrispondenti

• Partizionamento composto: usiamo due criteri per partizionare. Ad esem-pio potremmo e�ettuare un partizionamento per range e all'interno parti-zionare ulteriormente per lista

Sulle partizioni possiamo e�ettuare diverse operazioni: aggiungere dati, rimuo-verne altri, oppure e�ettuare l'operazione di truncating.Solitamente quando andiamo ad eliminare grosse quantità di dati, questa ope-razione richiede un incredibile quantità di tempo mentre tramite l'operazione ditruncate impieghiamo invece pochi centesimi di secondo. Ovviamente l'opera-zione di truncate può essere applicata anche alle partizioni.Tra le altre operazioni che possiamo fare abbiamo anche lo split e il merge dellevarie partizioni.Un'operazione un po' più particolare è quella di coalescing, che è in qualchemodo simile alla deframmentazione. Supponiamo di avere una certa quantitàdi spazio libero su disco, che però è distribuita uniformemente nel disco. L'o-perazione di coalescing raggruppa lo spazio libero per fare in modo che un �lesequenziale possa essere tranquillamente contenuto nello spazio libero. Questonon potrebbe essere fatto prima del coalescing perché magari lo spazio libero

26

Page 27: LabDB - MADB

sarebbe "spezzettato". Di fatto andiamo ad e�ettuare una sorta di defram-mentazione dello spazio libero. Tutto questo procedimento viene eseguito dalprocesso system monitor.

Una domanda che potremmo porci è: come gestire gli indici su una partizio-ne? Infatti la manutenzione della pagina si ri�ette anche in una manutenzionedell'indice! Solitamente quando andiamo ad eliminare una partizione andiamoanche ad eliminare gli indici associati, se invece usiamo un indice globale dob-biamo aggiornarlo. Di tutti questi procedimenti si occupa il processo systemmonitor.Vediamo invece una particolare famiglia di tabelle detta index organized table.Supponiamo invece di avere la situazione che segue: in una tabella con molticampi, tanti di questi campi appartengono alla chiave primaria. Per quantopossa sembrare strano in un caso come questo mantenere in memoria un indicepotrebbe costare più che mantenere la tabella stessa. Supponiamo infatti chetutti i campi tranne uno siano coinvolti nella chiave primaria, se l'unico camponon coinvolto occupa poco spazio(magari è un semplice intero) allora potrebbedarsi che l'indirizzo dell'indice(che solitamente è un valore complesso) occupipiù spazio del campo intero non coinvolto nella chiave primaria. Dunque l'indi-ce occupa di più perché sia l'indice che la tabella contengono tutti i campi dellachiave primaria ma inoltre l'indice ha un campo che occupa di più del camporimanente nella tabella.Solitamente questa situazione viene risolta andando ad utilizzare soltanto l'indi-ce "facendo �nta" che l'indice stesso sia la tabella. Questo viene fatto andandoad aggiungere all'indice anche i campi che non appartengono alla chiave.Questa soluzione ovviamente può essere applicata solo se sussistono le partico-lari condizioni che abbiamo elencato.

09 / 04 /2018

3.3 Indici bitmap e function based

Cominciamo a studiare gli indici di tipo bitmap. Sono costruiti per supportareindici su attributi con bassa cardinalità di valori distinti rispetto al numerototale di elementi. Inoltre sono pensati per un ambiente con pochi scrittori emolti lettori. Questo perché, come vedremo fra poco, è necessario prelevare unlock sull'intero indice per modi�carli. Per questo motivo gli indici bitmap sonopiù adatti ad un ambiente OLAP più che OLTP.

Esempio 1 : supponiamo di avere una tabella di clienti come quella mostratadi seguito

Notiamo che l'attributo Gender possiede due soli valori, M o F. Anche l'at-tributo Marital status possiede solo tre valori, Single, Married e NULL.Possiamo ad esempio de�nire un indice bitmap su ognuno di questi attri-buti. Li mostriamo in Tabella 3

27

Page 28: LabDB - MADB

ID Gender Marital status70 F NULL80 F Married90 M Single100 F NULL110 F Married120 M Single130 M NULL140 M Married

Tabella 2: Tabella dei clienti

KEY F M70 1 080 1 090 0 1100 1 0110 1 0120 0 1130 0 1140 0 1

KEY Married Single70 0 080 1 090 0 1100 0 0110 1 0120 0 1130 0 0140 1 0

Tabella 3: Indici bitmap

L'indice possiede una colonna per ognuno dei valori che può assumere l'at-tributo.Notiamo che possiamo gestire anche valori NULL nella seconda tabella.Infatti se il valore di marital status è pari a NULL, allora avremo entrambii bit settati a 0.

Quello che emerge è che per modi�care un indice bitmapped dobbiamo prelevareun lock sull'intera tabella e quindi questo spiega il discorso che facevamo pocofa sui lettori/scrittori.Analizziamo alcune proprietà degli indici bitmap

- Vantaggi: gestisce valori NULL. Possono essere partizionati localmente.Possono essere anche function-based(li vediamo fra poco). Possono essereindici secondari. In�ne sono ottimi per l'OLAP

- Svantaggi: non possono essere partizionati globalmente. Non vanno beneper l'OLTP

Vediamo qualche esempio di applicazione degli indici bitmapped

Esempio 2 : supponiamo di voler contare quanti dei nostri clienti provengonodalla regione "west". Ci è su�ciente contare tutti i bit pari a 1 nella bit-map sul campo west.

28

Page 29: LabDB - MADB

Possiamo anche facilmente costruire delle bitmap AND. Ad esempio se vo-gliamo sapere il numero di clienti donne dallo stato della Georgia possiamocostruire una bitmap sul sesso, una sullo stato e costruire una bitmap chesia l'and delle due. A questo punto basterà contare nuovamente i bit.

Completamente diverso è invece l'approccio degli indici function based che sononormali indici(ad albero) ma vengono creati dopo che abbiamo applicato unafunzione a tutti i dati. I vantaggi degli indici function based stanno nella loromaggior potenza, possono eseguire un calcolo pesante su un certo attributo esalvarne l'esito nell'indice, in�ne che incrementano il numero di situazioni in cuil'ottimizzatore può eseguire una scansione per intervallo invece di una scansionedell'intera tabella.Ad ogni modo, per comprenderci meglio, una funzione da utilizzare in questiindici potrebbe essere quella che calcola una combinazione lineare degli attri-buti oppure che converte tutte le lettere da maiuscole a minuscole per evitare iduplicati. . .Un vantaggio di questo approccio è che non abbiamo vincoli stringenti sui lock.L'unica questione di cui tener di conto è che la funzione che usiamo non dovreb-be produrre output diversi se l'input non cambia. Altrimenti non accederemomai ai dati giusti!

4 Prestazioni e tuning

Prima di procedere con il tuning vero e proprio del sistema, parliamo delTransparent Network Substrate.

4.1 Transparent Network Substrate, DB Link e 2PC

Il Transparent Network Substrate(TNS) è una componente software che gestiscele interazioni tra client e server. Per comprendere esattamente come funzional'intera comunicazione, all'inizio abbiamo un processo detto listener in esecu-zione sul server. Le caratteristiche del processo sono speci�cate in "HOME/-network/admin/listener.ora". Quando il processo listener riceve una richiestaavvia un processo server per la costruzione di una connessione dedicata.Sul client abbiamo invece un �le "HOME/network/admin/tnsnames.ora" dedi-cato a speci�care le caratteristiche del processo listener a cui dovrà connettersi.Ma di fatto il TNS cosa è? È un �le che possiede una serie di blocchi ognunorelativo ad una connessione. In ognuno di questi blocchi speci�chiamo il proto-collo della connessione, l'IP, la porta. . .E il TNS è fondamentale per parlare dei database link.

Supponiamo che un'azienda possieda due server e che un utente sul primo serverabbia bisogno di informazioni contenute nel secondo server. L'amministratoredel primo database fornisce all'utente i permessi minimi per e�ettuare l'opera-zione e dunque viene e�ettuata la richiesta. È importante notare che all'utente

29

Page 30: LabDB - MADB

verrà fornito un nome diverso e privilegi minimi quando richiede i dati nel se-condo database.Il vantaggio della tecnica database link è che ci permette di trasmettere datimediante una sola connessione e �ngere di avere a disposizione i dati di en-trambe le tabelle. Dobbiamo comunque fare attenzione perché se una tabella èreplicata in entrambi i database dovremmo cercare di capire a quale tabella cistiamo riferendo.

A questo punto, sapendo quali sono i dati che abbiamo a disposizione possiamoparlare del two phase commit, che si svolge in due fasi distinte

1. Preparazione: il processo che ha avviato il commit richiede a tutti i da-tabase se siano pronti ad e�ettuare il commit, e si mette in attesa dellerisposte. Se tutte le risposte sono positive scriviamo la marca di commitsul log e passiamo alla fase successiva, altrimenti avviamo la procedura dirollback

2. Commit: il coordinatore informa tutte le parti coinvolte della sua decisionedi commit/rollback

4.2 Tuning

Il procedimento di tuning è quello con cui andiamo settare opportunamente iparametri del database per massimizzare le prestazioni.All'interno di un progetto, prima procediamo con il tuning, maggiori sono ibene�ci che otteniamo, sia in fase di disegno, che di sviluppo, che di produzione.Intanto dobbiamo chiederci, quali sono gli scopi del tuning?

- Ridurre al minimo il numero di accessi ai blocchi

- Fare caching dei blocchi in memoria andando anche a condividere il codiceapplicativo

- Permettere una lettura/scrittura più veloce possibile

- Ridurre al minimo l'attesa per le risorse

- Ridurre l'impatto delle politiche di backup

Come e�ettuare il tuning? Tramite i seguenti passi:

1. Speci�ca degli obiettivi: andiamo a speci�care le quantità che vogliamotenere sotto osservazione

2. Raccolta dati: accumuliamo dati riguardo le quantità da tenere sottoosservazione

3. Modi�ca dei dati e delle regole

4. Analisi dei dati per generare le raccomandazioni

30

Page 31: LabDB - MADB

Figura 11: Fasi del tuning

5. Rivisitazione delle raccomandazioni

6. Implementazione delle raccomandazioni

L'intero procedimento viene mostrato in Figura 11Ad ogni modo esistono diversi parametri di cui possiamo fare il tuning e per

ognuno di essi abbiamo una fase dedicata: tuning del design, dell'applicazione,della memoria, dell'I/O, della contesa delle risorse e del sistema operativo.Ad esempio, andiamo nello speci�co per quanto riguarda la dimensione di unblocco Oracle nel database. La dimensione può spaziare dai 2k ai 64k. Comin-ciamo col notare che i blocchi più piccoli serviranno in ambito OLTP, mentrequelli più grandi nell'ambito OLAP. Solitamente, tralasciando i valori estremi 2ke 64k, utilizziamo blocchi di dimensione 8k-16k in ambito OLTP mentre usiamoblocchi di dimensione 16k-32k in ambito OLAP. Quali sono i vantaggi svantaggidei blocchi di dimensione ridotta?

• Vantaggi: riducono la contesa di risorse, non sprecano spazio per recordpiccoli, sono buoni per accessi casuali

• Svantaggi: contengono pochi record, ma il vero problema è che potrebbeessere necessario leggere più pagine per raggiungere le foglie di un indice

Chiaramente se la dimensione dei blocchi è grande abbiamo i vantaggi/svantaggiduali rispetto a quelli appena elencati.

Quali sono gli strumenti che Oracle mette a disposizione per e�ettuare il tu-ning? Ne abbiamo diversi e il primo che consideriamo sono delle viste detteDynamic Performance Views(dette colloquialmente V$). Vengono resettate almomento dello start up, contengono dati sulle strutture della memoria e datiutili per il tuning. Queste viste trovano una loro corrispondenza nelle fasi diavvio del database:

• Nella fase no-mount non abbiamo ancora un �le di controllo e quindiad esempio la vista V$sga raccoglie solo alcune informazioni di interesseriguardo la dimensione della memoria e i processi avviati

31

Page 32: LabDB - MADB

• Nella fase mount abbiamo, ad esempio, la V$data�le che legge le informa-zioni dal �le di controllo. Questa vista ci da un'idea dello stato dei data�ledel database in quel momento. Sono informazioni che potrebbero essereutili in fase di recovery

• Nella fase di open tutti i data�le sono raggiunti e controllati e da questomomento in poi tutte le V$ sono richiamabili. Una vista d'esempio po-trebbe essere la V$segment

10 / 04 /2018

Abbiamo visto che esistono alcune viste V$, ma in realtà sono molte, relative allamemoria, alla contention, ai dischi, alla sessione utente per poter ottimizzare. . .Le V$ possono anche essere utilizzate per raccogliere dati e statistiche. Questacollezione può avvenire o a livello di sistema per statistiche generali ma anchea livello di sessione per avere informazioni più speci�che.Da ora in poi vedremo come possiamo migliorare l'e�cienza di uno statementSQL. Abbiamo cinque modi: ristrutturare gli indici, ristrutturare gli statement,modi�care o disabilitare i trigger, ristrutturare i dati, in�ne mantenere le sta-tistiche correnti per preservare un piano di esecuzione. In questo momento cistiamo concentrando sulla fase di "Execution plan" che avevamo nominato inFigura 2.Abbiamo dunque un modulo ottimizzatore che deve creare il miglior piano diesecuzione. Oracle ha due strumenti per farlo:

• Manuale interno delle regole: insieme di regole indipendenti dalla queryspeci�ca. Il problema principale è che non tiene conto del problema cheha davanti

• Informazioni statistiche: suppliscono alle mancanze del sistema delle re-gole fornendo informazioni sul contesto

Dunque regole e informazioni statistiche ci permettono di ottimizzare.Se decidiamo di usare le statistiche dobbiamo mantenerle aggiornate. I metodidi aggiornamento si sono a�nati nel tempo: all'inizio c'era solo la analyze concui si faceva un calcolo completo o di stima. I calcoli di stima sono i più impor-tanti per l'ottimizzatore(a cui interessa sapere in che ordine di grandezza sta ladimensione di una tabella ad esempio). Dopo è stato introdotto l'analyze sche-ma con cui reiteriamo l'analyze per tutti gli oggetti di un determinato schema.L'ultimo metodo(ra�nato e gestito automaticamente da Oracle) è l'insieme deiDBMS stats che recuperano informazioni riguardo le tabelle.Quali sono le informazioni statistiche raccolte? Per le tabelle abbiamo il numerodi righe, il numero di blocchi liberi e occupati, il numero di righe in chained e inmigration(alta percentuale di chained e migration comporta tempi maggiori direcupero delle informazioni), l'ultima data in cui è stata fatta la analyze. Pergli indici abbiamo la profondità, il numero di foglie distinte per chiave, il nume-ro di elementi nell'indice. Nel tempo si sono aggiunte anche delle informazioni

32

Page 33: LabDB - MADB

speci�che delle singole colonne come il valore massimo e minimo o il numero divalori distinti.

Come guidare l'ottimizzatore nella scelta della modalità di ottimizzazione?(regole,statistica. . .)Il parametro di inizializzazione OPTIMIZER_MODE che può essere settato in quat-tro modi: rule, ovvero solo regole, choose basato sulla statistica, �rst_rows checerca di minimizzare il tempo di risposta, in�ne all_rows per minimizzare iltempo complessivo.In certi casi potrebbe essere utile minimizzare il tempo di risposta se dobbiamointeragire con un utente. Possiamo anche scegliere la modalità di ottimizzazioneanche per i singoli statement. Questo viene fatto tramite uno pseudo commento.Ovvero diamo una direttiva all'ottimizzatore sotto forma di commento.

Come possiamo chiedere all'ottimizzatore quale sia il piano? L'ottimizzatore celo può dire scrivendo il piano in una tabella dedicata detta Plan_Table. La Ta-ble_Plan può essere popolata automaticamente con lo statement EXPLAIN_PLAN.

Quando un utente nota un rallentamento non sa bene dove mettere le mani.Per questo Oracle mette a disposizione uno strumento detto SQL Trace Facili-ty. Per ogni statement ci fornisce delle statistiche a livello di sessione o di singolaistanza. Le informazioni vengono inserite in un �le di trace che possiamo andarea leggere tramite il comando tkprof. Questo comando partendo dal �le di traceproduce un �le txt facilmente leggibile.Possiamo speci�care alcune opzioni per il comando tkprof:

- Sort: va ad ordinare il �le in base ad un parametro(tendenzialmente iltempo di esecuzione)

- Print: intero che permette di stampare solo le prime n righe del �le

- Sys: introduce i dati di sys all'interno dell'analisi

- Table: speci�ca il piano per ogni statement eseguito

Di fatto quando apriamo il �le prodotto in output troviamo tutti gli statementnell'ordine da noi prescelto. E per ogni statement abbiamo una matrice chespeci�ca quante volte lo statement è stato chiamato in causa per la fase diparse(parsi�cazione dello statement tramite indagine del grafo sintattico, deipermessi e del piano di ottimizzazione), di execute(esecuzione in presenza di in-sert, update) e di fetch(che entra in gioco con lo statement di select). Mostriamola matrice in Figura 12

Notiamo che per ogni riga ci dice quante volte lo statement è stato invocato,i vari tempi di cpu, poi il numero di blocchi movimentati da disco e altre infor-mazioni.

Dalla versione 10 di Oracle è stata pensata una nuova modalità di gestionedel �le di inizializzazione. A supporto di grandi attività nasce la necessità di

33

Page 34: LabDB - MADB

Figura 12: Matrice prodotta dal comando tkprof

poter cambiare i parametri di inizializzazione a tempo di esecuzione. Vienecreato molto semplicemente con il comando Create spfile from pfile. Ilcambiamento viene poi fatto tramite il comando Alter system set seguito dalparametro che vogliamo modi�care.

5 Oracle Context

5.1 Large Objects

Per poter parlare del prossimo argomento, l'Oracle Context, dobbiamo primafare una panoramica sui Large Objects.I large objects sono insiemi di dati tipati pensati per contenere grandi quantitàdi dati(�no a 128 Tbytes). Ad oggi i database hanno a che fare con quattrodiversi tipi di dati:

- Semplici strutturati: organizzati in tabelle relazionali strutturati secondodelle regole di business

- Complessi strutturati: più complessi, pensati per contesti Object-Relational

- Semistrutturati: possiedono una struttura logica che però non è inter-pretabile da un database. Ad esempio i �le XML

- Non strutturati: non è organizzata secondo una struttura logica e ildatabase non riesce a interpretarla. Una fotogra�a potrebbe essere unbuon esempio

Notiamo che solo gli ultimi due tipi sono Large Objects. Per essere più precisii large objects si dividono in quattro categorie

• BLOB: i Binary Large Object possono contenere dati di qualsiasi tipo. Lefoto sono un tipico esempio di BLOB

• CLOB: i Character Large Object contengono dati in forma di carattere. Itesti di solito sono dei CLOB

• NCLOB: i National Character Set Large Object contengono informazioniin forma di carattere nazionale

34

Page 35: LabDB - MADB

Figura 13: Struttura dell'Oracle Context

• BFILE: gli External Binary File sono memorizzati esternamente al data-base e sono accessibili in sola lettura. Vengono utilizzati per memorizzare�le statici. I video sono un tipico esempio di BFILE

Per operare sui large object abbiamo il linguaggio PL/SQL oppure degli stru-menti Oracle come la Oracle Call interface, oppure la JDBC(Java DatabaseConnectivity).Di norma il DBMS può operare su large object tramite una serie di coman-di: open, close, converttoblob, converttoclob, copy, loadfrom�le, read, write,writeappend. . .

In particolare per quanto concerne i caratteri dobbiamo ricordare che ad ognidatabase è associato un insieme di caratteri che di�cilmente può essere cambia-to senza dover ricreare l'intero database. Per questo abbiamo anche i nationalcharacter set per fare riferimento a un insieme di caratteri alternativo.

5.2 Oracle Context

È uno strumento di indicizzazione dei testi messo a disposizione da Oracle perevitare di dover utilizzare componenti di terze parti. I vantaggi sono: è inclusoin tutte le edizioni Oracle, fornisce indici specializzati sui testi per recuperareinformazioni testuali. Inoltre può �ltrare ed estrarre informazioni dai principaliformati(docx, pdf, XML).Mostriamo in Figura 13 la struttura dell'Oracle Context

L'elemento più importante è il datastore che contiene i large object. I datidel datastore passano attraverso una fase di �lter in cui i dati strutturati(dcox,pdf) vengono elaborati e tradotti in HTML. Successivamente nella fase sec-tioner identi�chiamo le sezioni per ogni unità. Tipicamente l'output è ancora

35

Page 36: LabDB - MADB

un HTML oppure un XML. In seguito un lexer si occupa di separare le variecomponenti della frase in parole o token. Dopo, tramite la stop list andiamoa rimuovere le stop word e in�ne tramite l'indexing engine creiamo un OracleContext Index che contiente le liste invertite3 che rappresentano il contesto.Esistono due tipi di Oracle Context Index:

- Context: utilizzati per recuperare informazioni testuali, ovvero la classicaricerca

- Ctxrule: permette da un insieme di regole di classi�cazione e un docu-mento di andare a classi�care il documento

07 / 05 /2018

6 Utilità Oracle

In questo capitolo vedremo quattro funzionalità messe a disposizione dai da-tabase Oracle: in memory database, no-sql database, multitenant database ein�ne lo scheduler.

6.1 In memory database

Avevamo già visto che le esigenze dell'ambiente OLTP di�eriscono molto daquelle dell'ambiente OLAP. Con l'in memory database cerchiamo di far con-vivere questi due approcci dando due visioni di�erenti del dato: le righe perl'approccio OLTP e le colonne per l'approccio OLAP.L'emergere di questa doppia rappresentazione è dovuto al crollo dei costi del-l'hardware nel tempo.Attualmente la gerarchia di memoria è organizzata comesegue:

• Disco: contiene i dati "cold", poco usati

• SSD: contiene i dati "active"

• DRAM: contiene i dati "hottest", ovvero i più richiesti

Un aspetto positivo è che la visione a colonne ci permette di non utilizzare gliindici che utilizzavamo per l'analisi OLAP.Inoltre questa doppia rappresentazione non richiede un raddoppio della memo-ria. Richiede bensì un incremento dello spazio pari a circa il 20% che vieneoccupato all'interno della SGA. Questo incremento tanto limitato è dovuto adelle operazioni di compressione che vengono e�ettuate sui dati. Viene quindide�nita un'area di memoria dedicata detta column-store(o In-memory area) chefunge da supplemento al bu�er cache. Come già visto in precedenza possiamoanche impostare la dimensione di questa porzione di memoria mediante il para-metro INMEMORY_SIZE.Per usufruire di questa funzionalità dobbiamo eseguire tre passi:

3Così chiamate perché l'ordine delle parole è inverso a quello del testo

36

Page 37: LabDB - MADB

1. Con�gurare la capacità della memoria mediante il parametro INMEMORY_SIZE

2. E�ettuare l'alterazione delle tabelle o delle partizioni per inserirle in me-moria

3. Veri�care quali indici OLAP sia possibile rimuovere

Questi tre passi sono facili da eseguire e non richiedono restrizioni sulla parteSQL, né migrazione dei dati. Di fatto tutte le applicazioni possono continuarea funzionare immutate.Tutta la gestione della parte di memoria column-store contenuta nell'SGA vienedemandata ad un insieme di processi in background che comunque non limitanol'accessibilità del database.Ai dati viene anche associata una priorità che può essere: critica, alta, media,bassa e nessuna. Gli oggetti vengono caricati all'interno del database in basealla loro priorità. Ad esempio gli oggetti critici sono caricati immediatamentedopo l'apertura.La chiave di tutto questo sta quindi nella compressione che viene fatta sui dati.Il vantaggio principale sta sia nel risparmio in spazio ma anche in quello intempo perché Oracle può ad esempio applicare le clausole WHERE anche sui daticompressi. Abbiamo sei tipi di compressione:

- NO MEMCOMPRESS: dati inseriti senza compressione

- MEMCOMPRESS FOR DML: compressione minima ottimizzata per leprestazioni di manipolazione del linguaggio

- MEMCOMPRESS FOR QUERY LOW(default): ottimizzazione per mas-simizzare la prestazione della query

- MEMCOMPRESS FOR QUERY HIGH: ottimizzazione sia per il tempoma anche per lo spazio

- MEMCOMPRESS FOR CAPACITY LOW: ottimizzazione sia per il tem-po ma anche molto per lo spazio

- MEMCOMPRESS FOR CAPACITY HIGH: ottimizzazione pensata soloper lo spazio

6.2 NO-SQL database

Oracle fornisce tre versioni per gestire i NO-SQL database: lite, community edenterprise.Come sappiamo nei database NO-SQL i dati sono immagazzinati in nodi a lorovolta organizzati in shard. Ogni shard possiede un proprio fattore di replicazioneche indica quante copie(incluso l'originale) ci sono di un certo nodo.Come al solito la presenza di copie pone il problema della consistenza: dunque inun ambiente di questo tipo dovremo stabilire quanto ci interessa la consistenzae quanto l'e�cienza, che vanno in contrasto tra loro.

37

Page 38: LabDB - MADB

Figura 14: Architettura di un database multitenant

6.3 Multitenant database

Approccio che viene amichevolmente detto "a condominio". Permette una facilemovimentazione dei dati andando a far gestire a n processi in background n di-versi "sotto database". L'idea è di avere un unico "contenitore" in cui innestarediversi database.Questo approccio ha cinque principali obiettivi:

1. Innesto del database in un sistema orientato al cloud

2. Necessità di non perdere il patrimonio relazionale dei dati, ma di a�ancaread esso le potenzialità legate ai Big Data

3. Ottimizzare lo spazio in relazione all'accesso al dato

4. Sicurezza

5. Protezione del dato e ottimizzazione del �usso dati in caso di disasterrecovery

Il principale vantaggio di questo approccio sta nella scalabilità. Infatti possia-mo gestire un numero di database cinque volte superiore a parità di memoriautilizzata.Le principali componenti del database vengono mostrate in Figura 14

Le due componenti fondamentali sono:

• Root container: il primo "inquilino" del condominio. Contiene la SGAe altre sezioni di memoria, oltre ai �le di controllo, di undo e i redo log.Inoltre contiene metadati, schemi e utenti. Non dovrebbe contenere datautente. Supporta il backup tramite RMAN.

• PDB seed: il database innestato di default. Istanziato al momento dellacreazione del multitenant database, si comporta da template per la crea-zione di altri database da innestare. Gli oggetti al suo interno non possono

38

Page 39: LabDB - MADB

Figura 15: Struttura di un job

essere modi�cati dagli utenti e non può essere distrutto. Ogni CDB puòavere soltanto un seed container. Supporta il backup mediante RMAN.

Un altro vantaggio del multitenant database è che la creazione e la clonazionedi database è particolarmente semplice e viene fatta mediante qualche comandodi create, di alter. . .Questo ci permette di avere un alto livello di �essibilità, visto che molto facil-mente possiamo assegnare ad ogni database una diversa quantità di risorse.

6.4 Scheduler

Nell'ambito dei database, i programmi schedulati vanno ad automatizzare leprocedure di backup, reportistica, aggiornamento di viste materializzate e altricompiti che devono essere eseguiti periodicamente.Fino alla versione dieci esistevano i DBMS_jobs che permettevano di eseguirecompiti di re-scheduling. In seguito è stato introdotto uno scheduler che pos-siede una struttura molto più complicata. Infatti ad ogni job viene associatoun programma, una job class e altre proprietà de�nite in modo ben preciso.Mostriamo la strutturazione del job in Figura 15

39

Page 40: LabDB - MADB

Parte Seconda:

NO-SQL Database

Page 41: LabDB - MADB

12 / 03 /2018

7 Introduzione ai NO-SQL database

7.1 Modelli aggregati

L'approccio utilizzato nei NO-SQL database è diverso e nuovo. È utile pertrattare grandi moli di dati che non sono strutturati in modo rigido. Inoltrevedremo che nel caso di query distribuite si comporta molto bene.Perché utilizzare i database invece del �lesystem per immagazzinare �le? Letransazioni utilizzate dal database rispettano le proprietà ACID. Inoltre per-mettono di sviluppare grandi applicazioni delegando al DBMS alcune delle fun-zionalità più delicate. Per questo negli ultimi venti anni i database relazionalisono stati la soluzione più popolare.Purtroppo delegare al DBMS alcune funzionalità porta anche qualche svantag-gio. In particolare il database stesso diventa complicato da gestire e nei databaserelazionali emerge il problema dell'impedence mismatch, ovvero l'insieme di di�-coltà incontrate nel far interagire il RDBMS con del codice orientato agli oggettia causa dei problemi di mappatura di memoria dagli oggetti alle tabelle.In particolare quando viene sviluppata un'applicazione enterprise potremmoavere diversi team di sviluppo che usano ognuno un proprio linguaggio e questopotrebbe portare a grossi problemi di integrazione. La soluzione consiste nel-l'andare ad avere un database per ogni applicazione, ovvero per ogni team disviluppo. In questo modo il modello dei dati può essere scelto ad hoc.Di certo non possiamo ignorare che con l'avvento del web si sia di�uso un approc-cio orientato ai servizi(Service oriented applications SOA). In questo scenarioi servizi web vengono usati come un meccanismo di integrazione e le strutturedati possono essere molto più ricche e �essibili(XML, JSON).La di�usione del web ha anche portato ad avere molte più richieste in ingressoai servizi. Questo comporta una gestione più di�cile del carico di lavoro chetrova una risposta nei database distribuiti. Chiaramente i database distribuitisono molto più di�cili da studiare ma forniscono un miglior bilanciamento delcarico, oltre che una maggiore resistenza ai guasti.Il fatto che la situazione sia cambiata in modo così forte(da applicazioni a web,da centralizzato a distribuito) lascia pensare che possa esistere un nuovo approc-cio e infatti è proprio in questo contesto che si inseriscono i NO-SQL database.Quando parliamo di NO-SQL database ci riferiamo ad un movimento etero-geneo che propone una serie di modelli aventi alcuni aspetti in comune con ilmodello relazionale ma senza avere caratteristiche precise. Nel tempo i NO-SQLdatabase sono diventati sinonimo di:

- Database non relazionali, senza uno schema

- Progetti open source

- Database che vengono eseguiti su cluster

41

Page 42: LabDB - MADB

- Alternativa all'approccio ACID delle transazioni per quel che riguarda laconsistenza e la distribuzione dei dati

Assumendo che il modello dei dati sia il modo in cui percepiamo e manipoliamo inostri dati, lo distinguiamo dal modello di storage che descrive come il databaseorganizza e manipola internamente i dati. Nel seguito parleremo del modellodei dati come del modo in cui il database organizza i dati, dunque ci riferiremoad esso con il termine metamodello.Nel seguito chiameremo aggregato l'unità minima che il database riesce a trat-tare. Nei modelli relazionali l'aggregato era la tupla.Nell'ambito dei NO-SQL database si sono sviluppati quattro modelli di�erenti

• Chiave-valore

• A documento

• A famiglia di colonne

• A grafo

Torneremo su ognuno di questi modelli. Nel frattempo possiamo dire che i primitre modelli sono orientati agli aggregati. Il modello a grafo è troppo complessoper poter gestire le richieste di un singolo aggregato.

Esempio 1 : nel seguito faremo sempre riferimento al caso di studio che pre-sentiamo adesso. Supponiamo di avere il diagramma delle classi mostratoin Figura 16

Il problema principale del modello relazionale è che per evitare le ridon-danze di dati abbiamo una grande dispersione sulle varie tabelle. Questoporta ad avere delle query non sempre e�cienti. Se invece andiamo a co-struire una rappresentazione a documento abbiamo una serie di attributiche potremmo organizzare in due aggregati: uno relativo al cliente, l'altrorelativo al suo ordine. Notiamo che ad esempio potremmo avere l'indiriz-zo ripetuto in entrambi gli aggregati. Ovviamente questo comporta unaridondanza ma riduce anche il numero di aggregati cui dobbiamo accedere.

Nel complesso sembra che sia importante stabilire la struttura di un aggregato.Nell'esempio appena visto decidere di costruire due aggregati è stata una sceltaspeci�ca per il contesto. In e�etti i modelli possono anche essere classi�caticome aggregate ignorant o aggregate aware

• Aggregate ignorant: non stabiliscono esplicitamente la presenza di aggre-gati. Permettono facilmente di guardare i dati in modi diversi, quindi sonola scelta migliore quando non abbiamo una struttura primaria per mani-polare i dati. Sono modelli aggregate ignorant quelli relazionali e quelli agrafo

• Aggregate aware: stabiliscono esplicitamente la presenza di aggregati eaiutano la gestione di query su dati partizionati(magari su server diver-si). L'utilizzo degli aggregati porta con sé anche un'altra questione: non

42

Page 43: LabDB - MADB

Figura 16: Diagramma delle classi di una applicazione di e-commerce

esistendo il concetto di transazione l'atomicità non è più garantita se nonall'interno dell'aggregato stesso. Fanno parte di questa categoria i tre mo-delli già elencati in precedenza: Chiave-valore, a documento e a famigliadi colonne.

Vediamo qualche dettaglio in più sui modelli dei NO-SQL database.Il modello chiave valore gestisce gli aggregati come ammassi di bit, ovvero comedei BLOB(Binary Large OBject).Nel caso del modello a documenti invece possiamo andare a recuperare infor-mazioni inerenti i dati degli aggregati. Notiamo dunque che la grana è più �nerispetto al modello chiave-valore.I modelli a famiglia di colonne meritano invece una maggiore attenzione perchésono per noi contro intuitivi visto che non siamo abituati a pensare a colonne.La struttura è simile ad una map su due livelli

1. La chiave al primo livello è data dal numero della riga

2. La chiave al secondo livello è il nome della colonna, il cui valore è il valoredella colonna per quella riga

Molti database assumono la riga come unità di storage, cosa che migliora leprestazioni in scrittura. Esistono comunque molti scenari in cui sia necessarioleggere poche colonne di molte righe e in questa situazione si preferisce tenereinsieme molti gruppi di colonne dette appunto famiglie di colonne.Poiché le colonne possono essere aggiunte liberamente, possiamo avere due tipidi righe

43

Page 44: LabDB - MADB

- Righe skinny: hanno poche colonne usate per più righe

- Righe wide: hanno molte colonne(magari migliaia) e ogni riga può averecolonne molto diverse fra loro

L'ultimo modello che abbiamo visto è quello a grafo. I nodi sono molto semplicie possono rappresentare entità molto diverse fra loro. La complessità derivadalla rete interconnessa. Infatti questo modello è pensato per avere un'altae�cienza in lettura andando a navigare il grafo ma non è molto e�ciente inscrittura.

13 / 03 /2018

Un ulteriore caratteristica intrinseca del modello a grafo è che la sua strut-tura complessa rende di�cile separarne le componenti e dunque diventa di�cileandare a distribuire i dati su macchine diverse. Ne segue che solitamente sefacciamo uso di un modello a grafo andremo ad utilizzarlo in ambiente centra-lizzato. Questa conseguenza porta ad avere una minore tolleranza ai carichielevati ma anche il fatto che le proprietà ACID sono rispettate.Ma allora visto che devono essere usati in ambiente centralizzato, visto che nonsono orientati agli aggregati, cosa accomuna i modelli a grafo a tutti gli altrimodelli? Il fatto che ri�utino il modello relazionale e il fatto di essere schema-less, secondo cui non esiste uno schema ben preciso. La proprietà di schema-lessporta con sé alcuni vantaggi:

- Non dobbiamo avere in mente lo stesso schema di qualcun altro prima die�ettuare le procedure di memorizzazione

- Nei modelli orientati agli aggregati possiamo memorizzare come valore(ocolonna) ogni tipo di dato

- Nei modelli a grafo possiamo memorizzare nuovi archi e proprietà

- In generale permettono di avere una maggiore libertà durante lo sviluppo

Ovviamente tutta questa libertà porta con sé alcuni svantaggi come una maggio-re complessità di sviluppo e il fatto che si assuma uno schema implicito, ovveroassumere che certi nomi dei campi siano presenti e abbiano un certo signi�cato.In questo senso l'approccio schema-less sposta lo schema all'interno del codicedell'applicazione. Questi svantaggi possono essere gestiti in due modi

- Incapsulamento del database in una applicazione che gestisca le interazionicon l'esterno

- Organizzazione degli aggregati per aree. Dunque come visto nell'esempiodell'e-commerce dobbiamo andare a stabilire quali siano i "con�ni" degliaggregati

44

Page 45: LabDB - MADB

7.2 Materialised views

Un altro aspetto molto importante presente anche nei NO-SQL database è quellodelle materialised views. Una materialized view è una query che viene eseguitasaltuariamente e fornisce informazioni generali riguardo gli utenti(come infor-mazioni statistiche o altro). Anche se la query non è molto e�ciente vieneeseguita di rado e il suo risultato viene salvato e utilizzato più volte nel seguito.Chiaramente dopo un certo periodo di tempo il valore salvato dalla materialisedview potrebbe non essere aggiornato. Come gestire questo fatto? Abbiamo dueapprocci:

• Immediato: ogni volta che viene fatta una modi�ca ai dati aggiorniamo lamaterialised view

• Lazy: ogni tanto e�ettuiamo l'aggiornamento della materialised view(adesempio una volta a settimana)

8 Modelli di distribuzione dei dati

Abbiamo diversi validi motivi per e�ettuare una distribuzione dei dati:

- Gestire maggiori quantità di dati

- Potersi permettere rallentamenti sulla rete

Ad ogni modo insieme ai bene�ci elencati ci portiamo dietro alcune problema-tiche, ovvero che gestire i database distribuiti è complesso. Abbiamo due modidi e�ettuare la distribuzione:

• Replicazione dei dati

• Sharding: ovvero e�ettuare un partizionamento dei dati sui vari server

Nulla esclude che le due tecniche possano essere usate in parallelo.

8.1 Quattro modelli di distribuzione

Ad oggi le principali soluzioni al problema della distribuzione dei dati sono leseguenti:

• Single server: la soluzione più banale è non distribuire. Come dicevamo èla soluzione migliore per i database che usano il modello a grafo

• Sharding su server multipli: e�ettuiamo un partizionamento dei dati sudiversi server. In questo modo dovremmo distribuire il carico di lavoro. Vada sé che se i dati sono distribuiti male otterremo un partizionamento chenon ci aiuta. Dunque dovremmo tenere di conto di quali potrebbero esserele pagine più richieste, dei criteri di località spaziale. . . Queste questionisono talmente comuni che spesso i DBMS integrano degli algoritmi diauto-sharding. Notiamo che questa soluzione porta ad un aumento delleprestazioni ma non di robustezza

45

Page 46: LabDB - MADB

• Replica master/slave: viene scelto un nodo primario detto master che sioccupa di gestire le operazioni di scrittura sugli altri server, detti slave.Le operazioni di lettura (che non devono passare per il master) sono piùe�cienti. Quelle di scrittura invece no.Il vantaggio dell'approccio master slave è che se per un qualche motivo ilnodo master smette di funzionare le letture possono ancora essere e�et-tuate. Oppure potremmo anche fare in modo che se il nodo master nonfunziona, venga scelto un altro nodo che si occupi di gestire temporanea-mente le funzioni del master.Notiamo in�ne che avere i dati replicati sui vari slave potrebbe portaread avere una forma di inconsistenza tra i dati contenuti nei vari server.Notiamo quindi che esiste una forma di contrasto tra disponibilità e con-sistenza. Infatti tante più copie vengono mantenute in un numero elevatodi server, quanto più è probabile che si veri�chi un'inconsistenza tra i datidi un server e i dati di un altro server.

• Replica peer to peer: i nodi sono tutti "pari" tra loro. Le operazioni discrittura non devono passare per forza da un nodo e dunque le scritturesono distribuite. Anche in questo caso abbiamo il con�itto tra disponibilitàe consistenza. In particolare abbiamo maggiori rischi di con�itti write-write ovvero di con�itti in scrittura. Cosa succede se due nodi voglionomodi�care uno stesso dato di cui hanno ognuno una copia? Possiamoavere e�ettivamente un'inconsistenza.

Come gestire il problema dei con�itti in scrittura? Consideriamo prima i dueapprocci estremi. Da un lato potremmo decidere di avere massima consistenzaandando ad evitare ogni possibile con�itto. Ovviamente questo può essere fattosolo se permettiamo un maggiore tra�co di messaggi tra i server per permetternela coordinazione.L'approccio opposto che prevede la massima disponibilità non tiene invece diconto dell'inconsistenza dei dati. Questo approccio può essere utilizzato solo incerti casi.Abbiamo invece alcune vie di mezzo tra questi due approcci che fanno uso diun quorum. Basta che almeno metà dei nodi sia concorde sul valore di un datoper renderlo utilizzabile.Solitamente nel modello relazionale la consistenza è forte, mentre nei modelliNO-SQL abbiamo un maggior orientamento alla disponibilità. Per questi motivisono stati de�niti due approcci, uno pessimistico e uno ottimistico

- Pessimistico: si cerca di prevenire i problemi di consistenza andando adusare un lock

- Ottimistico: si suppone che i con�itti si veri�chino di rado e dunque nonusiamo sistemi di lock ma andiamo ad e�ettuare un test prima di accedereai dati per vedere se l'oggetto è stato aggiornato da qualcun altro

Notiamo che nel modello peer to peer dobbiamo anche gestire la consistenza disequenza, quella che ci garantisce che tutti i nodi vedano le operazioni sui dati

46

Page 47: LabDB - MADB

nello stesso ordine.Ad ogni modo esistono anche altre soluzioni al problema dell'inconsistenza: pos-siamo segnalare che si è veri�cata(e questo approccio è noto ai programmatoriche hanno avuto a che fare con i version control system) oppure possiamo de-legare la risoluzione del con�itto all'utente. Ad esempio utilizzando amazonpossiamo avere due carrelli diversi in contemporanea. Solitamente individuarequale sia il carrello giusto è un procedimento che viene delegato all'utente.Al di là del metodo utilizzato per risolvere le inconsistenze, viene detta �nestradi inconsistenza l'intervallo temporale in cui i dati non sono consistenti fra lo-ro. Riprendendo l'esempio del carrello di amazon, in questo caso la �nestra diinconsistenza è inferiore al secondo.Questo tipo di consistenza che non è immediata ma in qualche modo ritardataviene detta eventual consistency

26 / 03 /2018

8.2 CAP theorem

Come abbiamo visto la consistenza è importante e non va molto d'accordo conla disponibilità dei dati. Infatti talvolta non è accettabile avere una �nestradi inconsistenza mentre altre volte vogliamo concentrarci maggiormente sulladisponibilità dei dati. Notiamo che infatti è la quantità di nodi che abbiamoche determina quanto sarà lunga la �nestra di inconsistenza. Vediamolo conl'esempio che segue

Esempio 1 : una certa applicazione di blog distribuisce su tre nodi A, B, C lecopie delle proprie pagine. Se un utente scrive e la modi�ca viene inoltrataad un certo nodo A, nel momento in cui l'utente ricarica la pagina perveri�care di aver pubblicato il proprio contenuto potrebbe succedere chela risposta provenga dal nodo B. Se B non ha ricevuto l'aggiornamentodal nodo A, l'utente potrebbe vedere la pagina non aggiornata e potrebbesembrargli che il suo contenuto sia andato perso.

Situazioni come quella appena vista non sono di solito accettabili ma possonoanche essere risolte facilmente andando ad introdurre il concetto di sessione.Solitamente un utente parlerà con uno stesso nodo andando a mantenere a li-vello locale una qualche informazione(ad esempio l'indirizzo IP) del nodo concui ha comunicato �no ad ora.Ad ogni modo come possiamo fare un compromesso fra la disponibilità e la con-sistenza? A questo riguardo esiste un teorema, detto CAP theorem che era statoproposto in origine come una congettura e che è stato provato formalmente inseguito. Il teorema dice che, date le tre proprietà di consistenza(consistency C),disponibilità(availability A) e tolleranza al partizionamento(partition toleranceP), possiamo bene�ciare soltanto di due di queste tre proprietà. Riportiamogra�camente il teorema in Figura 17

Fondamentalmente o decidiamo di svolgere in locale tutte le nostre attività eotteniamo sia la consistenza che la disponibilità, oppure decidiamo di rinunciare

47

Page 48: LabDB - MADB

Figura 17: Rappresentazione gra�ca del CAP Theorem

o alla consistenza, o alla disponibilità.Nei NO-SQL database possiamo andare a costruire il nostro database cercandodi regolare e gestire opportunamente questi tre aspetti. Ad esempio possiamostabilire cosa debba fare un server se resta isolato dagli altri ma riceve una ri-chiesta di lettura da un utente. Cosa fare in tal caso? Se fornisce una rispostada la precedenza alla disponibilità mentre se decide di non rispondere da la pre-cedenza alla consistenza.Ad ogni modo esistono molte forme di compromesso. Ad esempio alcuni data-base come Redis o Post-Gre non distribuiscono i dati, oppure MongoDB gestiscel'hardware non funzionante andando a disabilitare i nodi e permettendo ai nodiattivi di rispondere al loro posto. . .Una caratteristica che non ci faremo mancare nel seguito sarà comunque quelladi partition tolerance. Dovremo sempre poter gestire le partizioni.

Un altro insieme di proprietà che spesso emergono nell'ambito dei NO-SQL da-tabase sono le proprietà BASE ovvero Basically Available, Soft state ed Eventualconsistency. Queste proprietà vengono nominate spesso anche se non sono an-cora state formalmente de�nite.

Adesso che abbiamo visto come rilassare le condizioni di consistenza, vedia-mo come possiamo rilassare le condizioni di durabilità. Sebbene possa sembrareun po' assurdo di poter scendere a compromessi anche sulla durabilità, in cer-ti casi questa proprietà non è fondamentale. Solitamente molte applicazionimantengono in cache dei dati. Ovviamente se abbiamo un guasto o un calo ditensione questi dati vanno persi. Ad ogni modo non è poi così grave se tra i datipersi abbiamo, ad esempio, i dati relativi alle sessioni utente.

48

Page 49: LabDB - MADB

8.3 Quorum

L'idea che sta dietro al meccanismo del quorum è la seguente: se un'operazionerichiede lo stesso dato a più di un nodo è meno probabile che un'eventualeinconsistenza non venga rilevata. Vediamolo più formalmente. In presenza diN nodi, abbiamo due tipi di quorum

• Quorum in scrittura: se riceviamo l'ack da almeno metà dei nodi per unascrittura allora va tutto bene. Dunque detto W il numero di ack ricevutiin scrittura, deve valere che:

W >N

2

• Quorum in lettura: per poter essere sicuri di star leggendo un valore consi-stente dobbiamo avere una forma di consenso sul risultato per un numerodi nodi pari a:

R > N −W

Vediamolo con l'esempio che segue

Esempio 1 : supponiamo di avere tre nodi a disposizione, dunque N = 3. Daquesto ne segue che W > 1.5 = 2 ovvero abbiamo bisogno di riceverealmeno due ack in scrittura per essere sicuri che ci sia un quorum. Inoltre,ne deve seguire che R > 3−2 = 1. Dunque abbiamo bisogno di contattarealmeno R > 1 nodi, ovvero almeno due nodi per essere sicuri di accorgercidell'inconsistenza.Notiamo che alternativamente potremmo richiedere che W = 1 rilassandola consistenza. Il che ci porterebbe a dover leggere R > 2 nodi. Ovverodovremmo leggere tutti i nodi per essere sicuri di ricevere dati consistenti.

8.4 Version stamp

Un altro meccanismo che viene spesso utilizzato è quello dei version stamp. Ilversion stamp è un valore associato ad un dato che ci permette di capire se il datoera già stato scritto. Capire se un dato è già stato scritto diventa importanteper gestire la concorrenza. Ad esempio in questo ambito abbiamo la tecnica dioptimistic o�ine lock con cui un client legge due volte ogni informazione chericeve riguardo una transazione e controlla che nulla sia cambiato nel tempo incui l'informazione viene mostrata all'utente.Qualcosa di simile viene fatto tramite gli e-tag nelle risorse http. Di fattoviene inserita un'informazione addizionale nell'header che serve a controllarela versione. Dunque l'e-tag è una forma di version stamp. Come possiamocostruire un version stamp? Abbiamo diversi modi

• Usare un contatore: ad ogni dato associamo un valore incrementale. Me-todo molto semplice ma richiede che un nodo centralizzato se ne prendacura

49

Page 50: LabDB - MADB

Figura 18: A sinistra l'approccio tradizionale. A destra l'esecuzione di una map

• Usare i GUID: associare ad ogni dato un valore casuale di dimensionemolto elevata, di modo che vi sia la garanzia di unicità. Possono esseregenerati da tutti ma non danno alcuna informazione temporale

• Usare un hash: stessi vantaggi e svantaggi dei GUID

• Usare un timestamp: associare una marca di tipo temporale. Facile daimplementare ma le macchine devono essere sincronizzate temporalmen-te. Inoltre dobbiamo stabilire quale sia la giusta grana del timestampaltrimenti rischiamo di avere modi�che indistinguibili.

Un'altra tecnica che però non viene utilizzata nell'ambito dei NO-SQL databaseè quella di mantenere una cronologia delle scritture in ogni nodo.

8.5 Paradigma map-reduce

Un paradigma molto popolare nella gestione dei big data è quello della map-reduce. Lo scopo di questo modello è di ridurre la quantità di dati trasferitisulla rete. L'approccio map-reduce nasce nell'ambito funzionale in cui il codiceè di fatto molto compatto. Sfrutta una funzione di map che va ad eseguiredelle operazioni di �ltraggio e di ordinamento, a cui fa seguire la reduce con cuiotteniamo delle statistiche o altre informazioni. Solitamente la map produce inoutput una lista di coppie <chiave, valore> e la reduce prende queste coppieper fornire in output una struttura aggregata. L'utilizzo di queste funzioni cipermette di inviare meno dati sulla rete come mostrato nell'esempio seguente.

Esempio 1 : se il lavoro deve essere fatto dalle funzioni map reduce possiamo oseguire il modello tradizionale e mandare tutti i dati ad un server che ese-gue le funzioni, oppure possiamo fare in modo che il server invii la funzionedi map agli altri nodi. A quel punto ogni nodo calcolerà la funzione suipropri dati ed invierà il risultato al server. In questo modo non dobbiamotrasferire tutti i dati ma solo la funzione e i risultati prodotti. L'approcciotradizionale viene mostrato nella parte sinistra della Figura 18, mentrel'approccio map-reduce viene mostrato nella parte destra di Figura 18.

50

Page 51: LabDB - MADB

Figura 19: Esecuzione di una map su due nodi diversi con partizionamentodell'output

27 / 03 /2018

sono tante le implementazioni del paradigma map-reduce. Una delle più no-te è quella di Hadoop in cui abbiamo vari split(che di fatto corrispondono aitask). Per ogni task eseguiamo l'operazione di map e di ordinamento. A questopunto, viene eseguita la copy verso il server dove verrà eseguita l'operazione direduce. Grazie all'elevata �essibilità di utilizzo, con hadoop possiamo gestiremodelli di rischio, di pubblicità, di sistemi di raccomandazione, di sicurezza. . .Vediamo un paio di esempi di applicazione

Esempio 2 : avendo a disposizione una serie di bollette distribuite di cui ciinteressa soltanto il costo mensile, potremmo eseguire una map localmenteper prelevare il costo, ed eseguire una reduce in locale per calcolare ilsubtotale. Inviarlo e rieseguire una reduce sul server che vada a sommarei vari subtotali ottenuti.

Esempio 3 : riprendendo l'esempio dell'e-commerce potremmo voler veri�carela quantità venduta di un certo tipo di prodotto. Allora, come mostria-mo in Figura 19, potremmo pensare di eseguire una map localmente edeseguire un partizionamento dei dati su cui eseguire la reduce.

Il partizionamento ci permette di eseguire più operazioni di map in paral-lelo.

Notiamo che nell'esempio precedente inviavamo dati replicati(3 occorrenze didragonwell ad esempio). Tramite l'operazione di combine eliminiamo i duplicati

51

Page 52: LabDB - MADB

Figura 20: Il calcolo della media deve essere eseguito dopo la reduce

prima di mandarli attraverso la rete. Ad ogni modo non tutte le operazionipossono essere precedute da una combine. Prendiamo ad esempio il calcolodella media mostrato in Figura 20

Notiamo come la total quantity e il number of orders possano essere precedu-ti da una combine, ma il calcolo della media deve essere fatto dopo l'esecuzionedella reduce.In certi casi potremmo anche avere bisogno di eseguire più map-reduce in ca-scata. Talvolta l'output di una map reduce intermedia potrebbe essere utile peraltre computazioni. Per questo motivo vengono solitamente salvate in forma diviste materializzate.Un altro utilizzo dell'approccio map-reduce è quello incrementale: molte map-reduce richiedono molto tempo e quindi se riceviamo nuovi dati non possiamorieseguire l'intero meccanismo di map reduce. Per questi motivi in certi casiviene utilizzata una map-reduce incrementale che esegua il minimo numero dioperazioni per aggiornare il valore della map-reduce. Esistono anche delle for-me più complesse di reduce che vengono eseguite soltanto se prima di esse vieneeseguita una map.

8.6 Persistenza poliglotta

Al giorno d'oggi abbiamo visto come possano esservi molte necessità diversenell'ambito dei database. L'idea della persistenza poliglotta è quella di utiliz-zare di�erenti database a seconda della circostanza. Il passaggio da databaseintegrato a database applicativo permette di utilizzare uno stile di interazionedi�erente ed elimina il problema dell'impedence mismatch. Dal punto di vistastorico potrebbe essere un buon momento per parlare di persistenza poliglottaperché negli ultimi vent'anni il modello relazionale non è stato messo in discus-sione mentre adesso abbiamo a disposizione molte alternative che fornisconodiverse funzionalità: strutture schemaless, replicazione, alta disponibilità, nuovimetodi di fare le query. Da questo ne segue che in base alle necessità possiamo

52

Page 53: LabDB - MADB

utilizzare un tipo di database diverso. Ad esempio se abbiamo bisogno di �es-sibilità sulle query useremo il modello relazionale tramite Oracle. Se dobbiamocostruire una map allora useremo un approccio chiave valore tramite un mem-cachedb. Se invece dobbiamo salvare una grande mole di dati su nodi di�erentiutilizzeremo l'approccio a colonne tramite Cassandra o Google BigTable. Seinvece abbiamo dei documenti associati ad id utilizzeremo un approccio basatosu documenti tramite MongoDB. In�ne se i dati sono altamente interconnessiandremo ad utilizzare un modello basato su gra�, tramite Neo4J.I principali vantaggi d'uso della persistenza poliglotta sono che non dovendoutilizzare per forza il modello relazionale possiamo avere un signi�cativo incre-mento prestazionale in certe situazioni. Un altro vantaggio arriva dall'esecuzionesu un cluster di commodity servers. Il cluster ci permette di scalare nettamentesulla mole di dati da trattare e questo è molto utile nell'ambito dei big data.Ovviamente l'utilizzo di così tanti modelli di�erenti potrebbe portare delle di�-coltà di interazione tra di essi. Dunque dovremmo comunque ponderare quandoe come utilizzare i nuovi modelli. Ad esempio per progetti accessori che nonportano grandi guadagni forse non vale la pena di utilizzare un nuovo modellocon tutte le complessità che ne derivano. Magari invece in un progetto principalepotrebbe valerne la pena.

9 Database chiave-valore: Riak

9.1 Elementi generali

Cominciamo a vedere alcuni modelli di database. Il primo che vediamo è di tipochiave valore. A titolo d'esempio studieremo Riak.I vantaggi sono molteplici: i dati possono essere di tutti i tipi perché visti comeBLOB. È un modello tollerante ai guasti server e le query possono essere fattevia web. Inoltre fornisce il supporto ai data center che hanno bisogno di bassalatenza e si adatta bene ad un elevato carico di lavoro. Un difetto è che diventadi�cile individuare i collegamenti logici fra le parti perché non esistono le chiavistraniere.Essendo pensato per il web tende a favorire la disponibilità ed è basato su unapproccio REST. Questo vuol dire che fa uso dei noti metodi REST come PO-ST, PUT, GET. . .Tutto questo viene fatto mediante una URL della forma:

http://SERVER:PORT/riak/BUCKET/KEY

dove al posto di "riak" abbiamo il nome del database. Notiamo che Riak dividele classi delle chiavi in bucket per fare in modo di evitare il più possibile lecollisioni tra chiavi.È possibile aggiungere nuovi valori anche se una chiave non viene data. In que-sto caso viene generata arti�cialmente e assegnata al valore.Le operazioni che possiamo fare, come dicevamo, sono quelle del modello REST.Ad esempio per aggiungere una chiave dovremo eseguire un comando della forma

53

Page 54: LabDB - MADB

POST http://localhost:8091/riak/words/mamma

-H "Content-Type: application/json"

-d '{"category" : "noun", "count" : 1}'

Analogamente potremo eseguire l'aggiornamento sempre con PUT e la can-cellazione mediante DELETE.

19 / 04 /2018

In riak vengono anche utilizzati i link, dei metadati che associano una chia-ve ad un altra chiave. Possiamo de�nirli come segue

</riak/bucket/key>; riaktag=\"tag name\"

Dove la parte prima del punto e virgola descrive la chiave verso cui punta illink mentre la seconda parte descrive il link stesso. Questi link sono unidire-zionali e non cambiano la chiave verso cui puntano. I link vengono aggiuntiovviamente mediante una PUT.I link vengono utilizzati per ottenere dati e per farlo dobbiamo inserire in codaall'URL una speci�ca del link con il seguente formato:/ _, _, _

Dove ogni tratto basso rappresenta una wildcard rispettivamente per: bucket,tag e keep. Cerchiamo di comprenderli con gli esempi seguenti:

Esempio 1 : se proviamo ad eseguire il comando:GET http://localhost:8091/riak/documents/1/_,_,_

andiamo a recuperare tutti i documenti collegati dal primo.Per e�ettuare un �ltro in base al tag dobbiamo andare a speci�care il se-condo termine del link. Ad esempio mediante:http://localhost:8091/riak/documents/1/_ ,successive, _

andiamo a recuperare tutte le coppie chiave valore successive alla prima.Questo meccanismo può essere iterato:http://localhost:8091/riak/documents/1/_ ,successive,_ /_ ,_ ,_

In queso modo andiamo ad ottenere i dati puntati dal link del bucketpuntato dal link dell'oggetto corrente.

L'ultimo che per ora non abbiamo utilizzato è il terzo, e viene detto keep. Setale campo è pari a 0, andiamo a restituire solo i dati ottenibili dall'ultimo passodel link, se invece è 1 andiamo a restituire anche tutti quelli dei passi intermedi.Riak possiede de�nito di default il meccanismo di map-reduce. L'input che ri-chiede è un array di oggetti JSON raggruppati per chiave. Nella parte "query"viene invece speci�cata sia la map che la reduce da applicare.Una cosa da notare è che possiamo andare a salvare una funzione di map comestored function in un bucket.Per ridurre l'impatto della map-reduce, possiamo andare ad e�ettuare unaselezionare sulle chiavi prima di eseguire la map.

54

Page 55: LabDB - MADB

Figura 21: Caso in cui N = 3, W = 1, R = 2

Esempio 2 : con il codice seguente:

"inputs":{

"bucket":"documents",

"key_filters": [["string_to_int"],["less_than",1000]]

}

andiamo a selezionare tutti i documenti la cui chiave è minore di 1000.

9.2 Memorizzazione

Come va a memorizzare le chiavi il software Riak? Applica alle chiavi unafunzione di hash e il risultato viene salvato in un nodo virtuale detto vnode. Ilvnode viene allocato su uno degli n server disponibili. L'insieme dei vnode vienegestito mediante una parola di 160 bit in cui ogni bit corrisponde ad un vnode.In Riak vengono mantenute diverse copie di uno stesso dato ma uno dei vnodeè il coordinatore che funge da master. In questo caso riemerge un discorso giàfatto in precedenza riguardo la consistenza dei dati distribuiti su multipli server.Riconsideriamo i tre parametri:

• N: il numero di nodi coinvolti nell'operazione

• W: il numero di nodi che devono dare conferma a�nché un'operazione discrittura venga considerata terminata con successo

• R: il numero di nodi che devono dare conferma a�nché un'operazione dilettura venga considerata terminata con successo

Consideriamo diversi casi possibili:

Esempio 1 : consideriamo il caso N = 3, W = 1, R = 2. Questa situazioneviene mostrata in Figura 21

In questo caso le operazioni di scrittura sono molto e�cienti ma in certicasi potremmo restituire ad un lettore una versione non aggiornata di undato.Il secondo caso è quello in cui N = 3, W = N , R = 1. Questa situazioneviene mostrata in Figura 22

55

Page 56: LabDB - MADB

Figura 22: Caso in cui N = 3, W = N , R = 3

Figura 23: Caso in cui N = 3, W = 1, R = N

Figura 24: Caso in cui N = 3, W = 2, R = 2

In questo caso le scritture non sono e�cienti ma la lettura è sempre cor-retta! Questo approccio funziona bene se le scritture sul database sonopiù rare. Viene spesso usato nei modelli relazionali.Un terzo approccio possibile è quello in cui N = 3, W = 1, R = N .Mostriamo questo caso in Figura 23

In questo caso la scrittura è e�ciente ma abbiamo una maggiore lentezzain lettura. Però possiamo sempre accorgerci se un dato non è aggiornato ein questo caso potremo porre rimedio tramite un timestamp ad esempio.L'ultima situazione è quella in cui N = 3, W = 2, R = 2. Viene mostratain Figura 24

In questo caso andiamo a leggere e scrivere la metà più uno dei nodi. In

56

Page 57: LabDB - MADB

questo modo siamo sicuri di accorgerci di una eventuale inconsistenza deidati

Come possiamo andare a speci�care i valori di N , W , R? Quando andiamo adeseguire il comando di PUT esiste un un campo dedicato chiamato "props".Notiamo che visto che Riak permette di avere copie diverse di uno stesso oggetto,permette anche la riconciliazione delle copie per uniformare il dato aggiornandole copie vecchie.Ogni oggetto possiede un vector clock in cui per ogni copia del dato abbiamo ilnumero del nodo che contiene la copia e un numero di versione per quell'oggetto.Quando un client vuole aggiornare un oggetto, va a speci�care la versione ot-tenuta da una versione precedente. Quando si veri�ca una scrittura potremmoavere più versioni di uno stesso dato, Riak ne tiene traccia tramite una strutturaad albero dove le varie copie di�erenti sono contenute nelle foglie.La riconciliazione viene fatta andando a controllare ed aggiornare il numero disequenza. Copie eventualmente inconsistenti vengono comunque mantenute �noa quando non viene superata un certa soglia del numero di versioni. Oltre quellasoglia la copia più vecchia viene eliminata.

23 / 04 /2018

Un'altra funzionalità di Riak è quella degli hook di pre commit e degli hookdi post commit. Questi hook sono delle porzioni di codice necessari per eseguiredelle operazioni subito prima o subito dopo un commit. Ad esempio un'opera-zione di post commit potrebbe essere una scrittura su log una volta che è statoe�ettuato il commit della transazione.Inoltre possiamo anche fare delle ricerche mediante le funzionalità di ApacheSolr, che restituisce un documento XML contenente i risultati della query.Complessivamente Riak è un modello di database distribuito in grado di gestirequeste situazioni evitando di avere un unico punto di fallimento

10 Database a colonne: HBase

Come avevamo già detto in precedenza, i database a colonne sono l'ideale pertutte quelle situazioni in cui abbiamo a che fare con dei dati eterogenei fra loro.Infatti possiamo avere degli oggetti con molte colonne e avere altri oggetti chenon ne hanno nessuna condivisa con i primi.HBase viene sviluppato come alternativa a Dynamo ed è pensato per gestiregrandi quantità di dati in un ambiente distribuito. È pensato per gestire alme-no cinque nodi e fornisce forti garanzie sulla consistenza dei dati. Le colonnedelle tabelle sono completamente variabili e non vincolate da uno schema.Inoltre nei database a colonne abbiamo delle caratteristiche che altri databaserelazionali non hanno: controllo di versione, compressione, garbage collection. . .Possiamo dire che uno degli scopi principali del database HBase è quello di ge-stire statistiche riguardo grandi quantità di dati.Notiamo che anche se i termini usati sono gli stessi, i database a colonna non

57

Page 58: LabDB - MADB

Figura 25: Rappresentazione del database dell'esempio 1

hanno nulla a che vedere con i database relazionali.Le operazioni in HBase possono essere fatte mediante una shell con il linguaggioJRuby oppure tramite degli script. Gli script possono essere utili per costruiredelle sezioni critiche.L'idea è di raccogliere le colonne in più famiglie di modo che ogni colonnasia composta da due parti: nome e quali�catore di colonna nella forma: "no-me:quali�catore"

Esempio 1 : consideriamo la Figura 25

In questo caso la famiglia di colonne riguarda i colori. Come vediamo laprima riga possiede tre colonne a riguardo ma la seconda neanche una sutale famiglia.

Ovviamente sulla tabella dell'esempio precedente possiamo eseguire delle ope-razioni di PUT e di GET. Per recuperare correttamente i dati tramite la GETandiamo a guardare il timestamp perché HBase permette di mantenere piùversioni di uno stesso dato all'interno del database. Dunque il timestamp piùrecente ci indica la versione più recente. Questo meccanismo è implementatoautomaticamente da HBase. Solitamente il sistema salva �no a tre versioniprecedenti di un dato. Possiamo comunque scegliere quante versioni salvare an-dando a settare il parametro VERSION. Ad esempio possiamo mantenere tutte leversioni precedenti impostando il parametro sul valore ALL_VERSION.Una domanda che potremmo porci è la seguente: quando andiamo ad aggiun-gere un attributo, dovremmo creare una nuova famiglia di colonne oppure no?Un criterio che potremmo utilizzare è il seguente: se questo nuovo attributo puòcondividere il timestamp con una colonna di un'altra famiglia, allora possiamoinserirlo in quella famiglia. Altrimenti possiamo pensare di creare una nuovafamiglia di colonne.

58

Page 59: LabDB - MADB

Vista la grande quantità di dati con cui abbiamo a che fare, in HBase soli-tamente si attiva un processo di compressione dei dati su cui poi andiamo ade�ettuare delle ricerche tramite i �ltri di Bloom. Col �ltro di Bloom andiamo acalcolare l'hash di un dato da inserire nel database e andiamo a settare a 1 i bitdi un array nullo, segnalati dall'hash calcolato. Quando vogliamo sapere se undato è presente nel database ne calcoliamo l'hash e veri�chiamo che tutti i suoibit siano settati a 1 nell'array. Se lo sono il dato potrebbe essere presente4, mase anche uno solo dei bit è settato a zero allora il dato sicuramente non c'è.L'ultimo metodo che abbiamo per interagire con HBase è quello che sfrutta ilprotocollo Thrift. Dopo aver creato su client e server i �le speci�ci per la comu-nicazione possiamo eseguire operazioni più o meno complesse.Un ulteriore strumento messo a disposizione da HBase è Whirr che è utilizzatoper la creazione di cluster di macchine virtuali su un cloud. È compatibile conalcuni dei più noti servizi di cloud, come Amazon Elastic Compute Cloud(EC2)e altri servizi. Whirr è comodo se vogliamo fare esperimenti di breve duratasu un cloud di terze parti a pagamento. Altrimenti è meglio avere un propriocluster di macchine.In conclusione HBase segue un modello a colonne che permette di avere unabuona scalabilità e che fornisce alcune funzionalità automatiche o meno, comeil mantenimento di versioni di�erenti.Potremmo dire che se Riak era l'ideale per applicazioni web-based, HBase èottimo per andare a gestire grandi quantità di dati.

11 Database a documenti: MongoDB

Nel modello a documenti possiamo gestire dati persistenti e annidati in formatoJSON. Uno dei vantaggi è che lo schema utilizzato non vincola i dati in modoprede�nito e questo ci garantisce una maggiore �essibilità.

Esempio 1 : supponiamo di voler gestire un database delle città. In questodatabase potremmo e�ettuare l'inserimento di nuovi dati come segue

db.towns.insert({

name: "New York",

population: 22200000,

last_census: ISODate('2009-07-31')

famous_for:["statue of liberty","food"],

mayor :{ name: "Michael Bloomberg",

party: "I"

}

})

Come abbiamo visto l'operazione di inserimento viene fatta mediante la insertmentre la ricerca viene fatta tramite una �nd.

4potrebbe perché a causa delle collisioni potremmo avere dei falsi positivi

59

Page 60: LabDB - MADB

Ad ogni oggetto andiamo ad associare un certo ObjectId che viene costruitousando quattro dati di�erenti: un timestamp, un client PC, un client processnumber e in�ne un valore incrementale.

30 / 04 /2018

In MongoDB tutti le entità sono oggetti Javascript. Anche il database stes-so è un oggetto interrogabile. Se richiediamo typeof db ci viene restituito iltipo del database che per l'appunto è un oggetto. Se invece chiediamo typeof

db.towns.insert ci viene detto che è una function.Ovviamente visto che possiamo avere delle funzioni possiamo de�nirle confunction name(args)body

Abbiamo tutta una serie di funzioni utili: la insert, la �nd. . .Ad esempio se vo-lessimo recuperare solo un certo attributo(oppure tutti gli attributi tranne uno)tramite la �nd, potremmo speci�carlo con un opportuno parametro. InfattiMongoDB mette a disposizione un sistema per e�ettuare query complesse. Adesempio tramite l'argomento name: / �P/ vorrebbe dire che dobbiamo recupe-rare tutti gli elementi il cui attributo nome inizia per P . Di norma l'operatorecondizionale è fatto come segue:{$op : value }

Inoltre le condizioni possono anche essere messe all'interno di un oggetto

Esempio 2 : andando a speci�care l'oggetto

population_range['$lt']=1000

population_range['$lt']=10

nella funzione �nd possiamo speci�care la condizione

population: population_range

con questa condizione andremo a considerare il vincolo contenuto nelvettore population_range

In MongoDB possiamo e�ettuare delle ricerche tramite un valore parziale. Sealmeno un elemento soddisfa la condizione a�nché l'oggetto venga restituito.Possiamo anche cercare in oggetti annidati tramite la notazione puntata.Per le query di ricerca abbiamo anche il valore exists che serve per cercaretutti gli oggetti che possiedono speci�cato quell'attributo.

Esempio 3 : andando ad e�ettuare la query

db.towns.find(

{'mayor.party' : {$exists: false}}

)

andiamo a recuperare tutte le città il cui sindaco non ha un partito politicospeci�cato.

60

Page 61: LabDB - MADB

Abbiamo anche la funzione count per contare gli elementi in una tabella.Dobbiamo però fare attenzione al fatto che se per la �nd speci�chiamo una seriedi condizioni logiche, non è detto che debbano essere tutte veri�cate su unostesso oggetto. Di default potrebbero essere soddisfate su oggetti diversi. Seinvece vogliamo che più condizioni logiche valgano su un solo oggetto dobbiamoopportunamente speci�carlo.In MongoDB la disgiunzione viene espressamente speci�cata mediante la scrit-tura dell'operatore or.Le operazioni di aggiornamento richiedono due parametri:

• Un criterio di ricerca(speci�cato allo stesso modo della �nd)

• Un secondo parametro che viene speci�cato in due modi

� un oggetto con i nuovi valori per i campi. Notiamo che con questometodo sostituisce l'oggetto precedente andando ad eliminare i campinon speci�cati.

� una speci�ca operazione di modi�ca set che va semplicemente amodi�care un campo speci�co

Esistono anche altri operatori speci�cabili come push e pop.Un altro metodo in MongoDB è il findOne che va a restituire il primo oggettoche rispetta la condizione.Dunque in base a tutto quello che abbiamo detto sicuramente MongoDB è molto�essibile nelle query. Purtroppo non funziona molto bene con le join perché èun sistema pensato per ambiti distribuiti.In MongoDB possiamo anche inserire dei riferimenti ad altri oggetti mediantela notazione $ref.

In MongoDB funzioni più complesse come la map-reduce devono essere spe-ci�cate dall'utente. Questo tipo di funzioni vengono dette decision function.Tramite una sintassi più standard andiamo a speci�care le condizioni da veri�-care tramite un $where.Questo tipo di query sono solitamente meno e�cienti perché non possono av-valersi di indici speci�cati in precedenza ma vanno a fare una ricerca su tutti idocumenti memorizzati. Inoltre richiedono il trasferimento di tutti i documentidal server al client. Inoltre se anche un solo oggetto non ha il campo speci�cato,l'intera query fallisce. Dunque potremmo dire che è un metodo molto delicato.Il vantaggio è che una query è più semplice da speci�care.

Come possiamo costruire un indice in MongoDB? Possiamo farlo come segue

db.<nomeCollezione>.ensureIndex(argomenti)

gli argomenti possono essere diversi, come il numero di campi indicizzati. . .In MongoDB i dati sono già organizzati a mappa, quindi se vogliamo e�ettuarela map-reduce, dobbiamo eseguire solo la reduce. Solitamente la reduce viene

61

Page 62: LabDB - MADB

Figura 26: Utilizzo dei query router

sostituita con una groupBy perché viene considerata più e�ciente.MongoDB permette anche di salvare nel proprio catalogo delle funzioni comedelle funzioni Javascript. Questo viene fatto tramite il comandodb.system.js.save(argomenti)

le funzioni salvate nel catalogo di sistema viene eseguita mediante il comandodb.eval(nome)

Cosa succede se non speci�chiamo eval per invocare la funzione? In questo casola funzione viene eseguita sul client e questo non è e�ciente perché dobbiamoandare a trasferire grandi quantità di dati sulla rete verso i client. Se vogliamoeseguire la funzione sul server dobbiamo usare la eval.Per eseguire la map reduce con MongoDB dobbiamo eseguire unadb.runCommand(argomenti)

in cui andiamo a speci�care su quale collezione vogliamo fare la map-reduce,quale è la funzione di map e quale quella di reduce. Inoltre dobbiamo speci�ca-re dove andare a restituire l'output.

In MongoDB possiamo anche e�ettuare le operazioni di replica e sharding (di-stribuzione dei dati in nodi diversi).I replica sets mantengono delle repliche dei dati su più nodi. Ma per avere unadistribuzione equa delle repliche nei nodi, andiamo ad e�ettuare lo sharding.Questo ci permette di gestire il caso in cui alcuni nodi non sono raggiungibili.In questo caso un nodo viene scelto come master e continua a rispondere allequery andando a richiedere le repliche.Di tutte queste operazioni si occupano i query router ovvero delle interfacce tral'applicazione client e i cluster su cui è stata e�ettuata l'operazione di sharding.Questa situazione viene mostrata in Figura 26

Solitamente un replica set è un gruppo di processi che servono per mante-nere alta la disponibilità. Un membro dell'insieme viene detto primario e può

62

Page 63: LabDB - MADB

eseguire le scritture e le letture. Gli altri processi, detti secondari, sono abilitatiad eseguire solamente le letture.Gli shard sono delle partizioni del database costruite in base ad una certa chia-ve. Quale attributo scegliere come chiave di sharding? Magari l'attributo conmaggiore cardinalità che dovrebbe portare a delle divisioni più uniformi. Oppu-re potremmo usare la frequenza con cui gli oggetti vengono richiesti. In questomodo dovremmo ridurre il carico di lavoro in modo più equo. Il sistema si oc-cuperà di distribuire i dati sui vari nodi in modo da rendere il carico di lavorouniformemente distribuito.

08 / 05 /2018

Se nessuno dei criteri �nora descritti permette di suddividere in modo uniformeil carico fra i nodi, allora possiamo utilizzare una suddivisione in base ad unafunzione di hash. In base a questo dovremmo avere una divisione che sebbenenon segua un criterio identi�cabile dovrebbe essere equa.

In certi casi succede comunque che ad un certo punto il carico di lavoro nonsia ben distribuito. In tal caso possiamo procedere ad eseguire una separazionedei chunk oppure e�ettuare una migrazione dei dati.

Come dicevamo, un nodo viene detto primario e solo quel nodo può occuparsidelle scritture. Ma cosa succede se tale nodo non è disponibile? In quel casoviene selezionato un nuovo nodo primario, solitamente il più aggiornato. In certicasi viene invece e�ettuata una votazione fra i nodi disponibili per stabilire chidebba essere il nuovo nodo primario. Se si veri�ca una situazione di parità, unnodo designato detto arbiter che non possiede i dati e non può diventare nodoprimario, va ad esprimere il suo voto per risolvere la situazione di parità.Ovviamente l'intero procedimento di votazione viene avviato quando i nodi per-dono contatto con il nodo primario per oltre un certo periodo di tempo stabilitoda un timeout.Come in tutte le situazioni in cui i dati sono replicati, il problema della consi-stenza si pone naturalmente. In MongoDB possiamo stabilire mediante il pa-rametro read_concern quanto ci interessa che i dati reperiti siano aggiornati.Tale parametro può assumere i seguenti valori:

- local: il dato restituito non è necessariamente il più recente. Però èaggiornato a livello di sessione

- available: in questo caso viene preso il dato minimizzando la latenza.Ovviamente non abbiamo alcuna garanzia di ottenere il dato aggiornato

- majority: garantisce che il dato restituito sia coerente sulla maggioranzadei nodi. Dunque abbiamo consistenza ma i tempi di latenza sono certa-mente maggiori. In questo caso possiamo anche risolvere il problema discritture in con�itto

63

Page 64: LabDB - MADB

- linearizable: metodo simile al precedente. Di�erisce soltanto nel caso incui la maggioranza dei server sia in crash e in quel caso la consistenza nonè garantita

12 Database chiave-valore: Redis

Tramite il database Remote dictionary server(Redis) e�ettuiamo un immagaz-zinamento dei dati della forma chiave-valore. Il vantaggio è che abbiamo dellestrutture dati molto avanzate come code, stack, insiemi e altro ancora.Inoltre è un sistema molto e�ciente in scrittura che ci permette di modi�care ereperire le informazioni mediante dei semplici metodi get & set.Per eseguire più operazioni di seguito dobbiamo utilizzare il comando MULTI

a cui facciamo seguire tutte le operazioni da eseguire. Quando abbiamo �nitol'inserimento della coda di operazioni, le lanciamo tramite un comando di EXEC.Come dicevamo, in Redis possiamo utilizzare diverse strutture dati e per operaresu ognuna di esse esiste una versione diversa dello stesso comando. Ad esempiotutti i comandi per gli insiemi cominciano per S, quelli per gli insiemi ordinatiiniziano per Z, quelli per l'hash cominciano per H, quello per le liste per L. . .Dunque avremo delle HGET e delle LGET e così via.Ed ovviamente visto che parliamo di database possiamo e�ettuare tutte quelleoperazioni tipiche come le join, le range. . .

Un'altra funzionalità messa a disposizione in Redis è quella di una cache moltoveloce da accedere in cui gli elementi vengono mantenuti soltanto per un certotempo. Tale tempo viene stabilito singolarmente per ogni oggetto mediante ilcomando EXPIRE

Esempio 1 : supponiamo di eseguire il seguente codice

> SET ice "I'm melting"

OK

EXPIRE ice 10

(integer)1

In questo caso la chiave ice verrà eliminata dopo dieci secondi dalla cache

13 Database a grafo: Neo4J

In Neo4J i dati sono immagazzinati come gra� in senso matematico. Dunquesono una collezione di nodi e archi a cui possiamo associare delle proprietà. Inquesto caso ci concentriamo maggiormente sulle relazioni fra i dati. Il princi-pale vantaggio è che i dati possono essere molto eterogenei fra loro, secondo ilprincipio che "sul lungo periodo, tutti i campi divengono opzionali".Per gestire i nodi viene utilizzato un linguaggio dedicato detto Groovy che pog-gia su un'interfaccia REST. Inoltre vengono usati algoritmi speci�ci per reti e

64

Page 65: LabDB - MADB

Figura 27: Grafo dell'esempio 1

gra� di grande dimensione che gli permettono di interfacciarsi bene con la JavaUniversal Network Graph(JUNG).È un database altamente scalabile che gestisce le copie dei dati secondo unmetodo master-slave. Inoltre garantisce il rispetto delle proprietà ACID. Pergarantire un'elevata disponibilità, i nodi slave possono essere scritti e sincroniz-zarsi solo in seguito con un nodo master.

Per andare ad e�ettuare query sul grafo viene utilizzato un linguaggio dedi-cato detto Gremlin. È in qualche modo simile a jQuery.Per accedere ai nodi di un certo grafo g possiamo utilizzare la notazioneg.VInvece, per accedere agli archi possiamo utilizzare la notazioneg.EÈ importante l'utilizzo della keyword �lter per andare a stabilire delle condizio-ni logiche con cui e�ettuare le query.Vediamo un esempio di utilizzo di Gremlin.

Esempio 1 : supponiamo di voler gestire una rete di distribuzione del vino.Abbiamo tre entità che ci interessano per questo dominio: il tipo di uvautilizzata, la casa di produzione del vino, e una rivista mensile che recen-sisce vini. Possiamo notare che i dati sono eterogenei fra loro.Li rappresentiamo in un grafo Neo4j come quello mostrato in Figura 27

Per ottenere gli archi uscenti da un nodo:

gremlin>g.V.filter{it.name==Wine Expert Monthly'}.outE

==> e[0][1-reported_on->0]

dove la riga che comincia con ==> indica la risposta della query.Se invece volessimo ottenere tutti i nodi connessi ad un certo nodo me-diante degli archi entranti, potremmo farlo come segue:

gremlin>g.V.filter{it.name=='Wine Expert Monthly}.outE.inV.name

==> Prancing Wolf Ice Wine 2007

Esiste anche un altro linguaggio per e�ettuare le query che viene detto Cypher.La sintassi è più simile a quella dell'SQL ma è assai più criptica e meno leggibile

65

Page 66: LabDB - MADB

Figura 28: Grafo dell'esempio 2 dopo l'aggiunta di alcuni nodi e archi

di quella di Gremlin.Come dicevamo, l'aspetto migliore di Neo4j è che possiamo aggiungere datimolto eterogenei fra loro. Vediamolo con l'esempio che segue

Esempio 2 : supponiamo di voler aggiungere alla rete dell'esempio precedentequalche nuovo elemento. Ad esempio vogliamo aggiungere delle personeche hanno delle relazioni di amicizia fra loro e ad alcune di queste personeinteressa la catena di produzione del vino. Potremmo farlo in modo moltosemplice andando ad eseguire alcuni comandi come

tom=g.addVertex([name: 'Tom'])

kabinett = g.V.filter{it.name=='Prancing Wolf Kabinett 2002'}.next()

g.addEdge(tom, kabinett, 'likes')...

Il risultato ottenuto dopo altre aggiunte sarebbe qualcosa di simile aquanto mostrato in Figura 28

66