Progettazione del database: schema e scalabilità

Completato

I database, come si può immaginare, includono un'ampia gamma di applicazioni e requisiti. A questo proposito, verranno illustrati alcuni schemi progettuali specifici che gli autori di database devono seguire per la creazione dei sistemi di database.

Applicazione dello schema

I sistemi di database, in generale, richiedono alcune informazioni riguardanti i tipi e le strutture dei dati da archiviare nel database. Con i sistemi di database relazionali, lo schema viene definito formalmente nei termini seguenti:

  • Tuple (righe) che sono costituite da attributi (colonne), ognuna di un determinato tipo.
  • Una relazione (tabella), che è costituita da più tuple dello stesso tipo.
  • Vincoli, che definiscono un set di regole per tuple, attributi e relazioni.

Gli schemi non sono semplici linee guida, ma vengono applicati nei sistemi relazionali. I database basati su schema offrono i vantaggi seguenti:

  • Gli schemi esprimono il modello di dati in modo da consentire la creazione di query e operazioni complesse. Un join (in cui i dati vengono dedotti da due o più tabelle distinte), ad esempio, è relativamente semplice da esprimere in un database relazionale.
  • Gli schemi possono contenere vincoli, che possono essere usati per applicare la logica del programma a livello di database. Vincoli semplici, ad esempio, possono controllare se l'età di una persona è un numero positivo, mentre un libro contabile implementato come set di tabelle in un database relazionale può applicare la proprietà (usando un vincolo complesso) che richiede che la somma di tutti i crediti e i debiti nel sistema sia uguale a zero. Il sistema può rifiutare o restituire automaticamente le transazioni che violano tali vincoli.
  • I sistemi relazionali sfruttano le informazioni fornite nello schema per creare piani di query elaborati ed efficienti, consentendo al database di rispondere in modo efficiente alle query relative ai dati archiviati.

L'imposizione rigida di uno schema rappresenta tuttavia anche una barriera alla flessibilità. Con l'evolversi di un'applicazione, la modifica dello schema di una tabella già popolata con righe è difficile, se non impossibile, a seconda della tabella e dei vincoli specificati.

Dall'altra parte, ci sono i sistemi con schemi flessibili o senza alcuno schema. Un esempio di un sistema praticamente privo di schema è un archivio chiave-valore generico, che essenzialmente funge da mapping tra le chiavi di un determinato tipo e un valore associato. Alcuni archivi chiave-valore sono molto flessibili e consentono l'archiviazione di qualsiasi dato binario arbitrario con una chiave specifica. Alcuni archivi chiave-valore, come AWS Dynamo DB, richiedono che il tipo della chiave (stringa, Integer e così via) venga reso esplicito quando viene creata una nuova tabella. Alcuni sistemi consentono la presenza di valori annidati negli attributi dei dati, in genere archiviati come JSON o XML, ad esempio l'archiviazione tabelle di Azure.

Un'altra variazione è costituita da sistemi come Bigtable di GCP e Apache HBase, che hanno uno schema semi-flessibile. Questi sistemi richiedono che venga dichiarato il numero di colonne quando viene creata una tabella, ma una colonna può contenere un numero qualsiasi di colonne secondarie annidate. Questi sistemi verranno descritti in dettaglio nel modulo successivo.

Transazione ed elaborazione analitica

Una scelta di progettazione importante per l'ottimizzazione di un sistema di database consiste nell'ottimizzare il tipo comune di query che verranno ricevute. Ci sono due modelli principali nei carichi di lavoro dei database.

I carichi di lavoro transazionali, noti anche come OLTP (Online Transactional Processing), sono carichi di lavoro costituiti principalmente da transazioni online brevi. I carichi di lavoro OLTP sono costituiti principalmente da inserimenti, aggiornamenti e/o eliminazioni. L'enfasi nei sistemi OLTP è posta sull'elaborazione rapida delle query e sul mantenimento dell'integrità dei dati negli ambienti in cui si verifica l'accesso simultaneo. Un valido esempio di carico di lavoro OLTP è costituito dalle transazioni finanziarie. Le query in genere coinvolgono solo alcune tabelle e righe e non richiedono vaste scansioni del database.

Dall'altra parte, determinati sistemi aggregano e analizzano i dati per ottenere informazioni dettagliate e ricavare informazioni dai dati. Tali sistemi sono detti OLAP (Online Analytical Processing). I sistemi OLAP prevedono in genere un volume inferiore di transazioni, ma le singole query possono essere complesse e coinvolgere calcoli aggregati che si estendono su più righe e più tabelle. Le query OLAP tipiche hanno quindi tempi di esecuzione significativamente più lunghi rispetto alle query OLTP.

Il video seguente offre una panoramica di OLTP e OLAP:

Scalabilità

Con il passare del tempo, quando la base di utenti e i dati di un sistema di database aumentano, il sistema può richiedere una forma di scalabilità, che espande la capacità e/o le prestazioni per supportare più utenti o dati o entrambi. Il ridimensionamento del database è complesso per diversi motivi, che verranno illustrati in dettaglio nel video seguente:

Scalabilità verticale

La scalabilità verticale (o aumento delle prestazioni) è il processo di aumento della capacità di un database o della possibilità di gestire il carico senza aggiungere altri host. È possibile ottenere questo risultato tramite aggiornamenti hardware come una CPU più veloce, una maggiore quantità di RAM o dischi con più capacità e/o più operazioni di I/O al secondo (IOPS). La scalabilità verticale è limitata dalla quantità di CPU, RAM e disco che è possibile configurare in un singolo computer.

Scalabilità orizzontale

La scalabilità orizzontale (o ampliamento di livello) indica il ridimensionamento dei database aggiungendo più nodi per gestire le query del database. Diversi prodotti RDBMS offrono modalità diverse di scalabilità orizzontale, tra cui replica e partizionamento orizzontale dei database. Con la replica, gli stessi dati vengono archiviati in più nodi. In questo modo, il sistema RDBMS è in grado di gestire richieste aggiuntive in parallelo, con il conseguente aumento del numero di transazioni al secondo. Questo approccio funziona quando il database ha un'intensa attività di lettura. Con il partizionamento orizzontale, una tabella di grandi dimensioni viene partizionata tra più nodi, in genere in un indice o in una chiave. La quantità di dati condivisi tra i nodi in questo caso è limitata e la condivisione limitata è preferibile perché riduce i problemi di coerenza dei dati replicati.

La replica è il processo di duplicazione dei dati in più server per aumentare il numero di percorsi disponibili per le singole unità di dati. I dati possono essere replicati per motivi di prestazioni, disponibilità e/o tolleranza di errore. I dati replicati consentono prestazioni più veloci, in particolare per le letture, perché la replica permette l'accesso parallelo a più copie degli stessi dati. La replica supporta la disponibilità e la tolleranza di errore, in quanto in caso di errore di una parte del sistema di database i dati sono disponibili in un percorso di backup.

Un altro metodo, ortogonale alla replica, è il partizionamento orizzontale. Il partizionamento orizzontale è il processo mediante il quale i dati vengono suddivisi in sezioni (note come partizioni) e distribuiti in più sistemi di database. A differenza della replica, ogni partizione funge da unica origine per il subset di dati contenuti. Il partizionamento orizzontale è una tecnica usata in modo specifico per migliorare le prestazioni dei database e, in particolare, le prestazioni di scrittura.

In un caso ideale, un database partizionato distribuirà uniformemente i dati in tutte le partizioni. Questo risultato è tuttavia difficile da raggiungere, in quanto la distribuzione dei dati in tutte le partizioni deve essere più o meno bilanciata. Una tecnica diffusa che rappresenta il pilastro di molti sistemi di database correnti è l'hashing coerente.

L'hashing coerente è un tipo speciale di tecnica di hashing che consente l'espansione di una tabella hash in modo efficiente. Se K è il numero totale di chiavi e n è il numero di bucket in una determinata tabella hash, l'hashing coerente richiede che venga rieseguito il mapping solo di K/n chiavi in media ogni volta che viene aggiunto un nuovo bucket alla tabella hash1.

Alcuni sistemi usano una combinazione di replica e partizionamento orizzontale per offrire prestazioni elevate mantenendo la disponibilità elevata e la tolleranza di errore. Quando si usa la replica, tuttavia, la coerenza rappresenta una problematica importante, come verrà illustrato di seguito.


Riferimenti

  1. Karger, David e Lehman, Eric e Leighton, Tom e Panigrahy, Rina e Levine, Matthew e Lewin, Daniel (1997). Consistent Hashing and Random Trees: Distributed Caching Protocols for Relieving Hot Spots on the World Wide Web Documentazione del ventinovesimo simposio ACM annuale sulla teoria informatica

Verificare le conoscenze

1.

Si supponga di progettare un sistema di archiviazione per un'applicazione che estrae tabelle dalle pagine Web. L'applicazione prevede l'assegnazione di un identificatore univoco a ogni tabella e quindi l'archiviazione della tabella nel database in un formato basato su XML non elaborato. Quale tipo di sistema può essere più adatto per questo tipo di applicazione?

2.

Un sistema di prenotazione aerea usa un database per tenere traccia di passeggeri, compagnie aeree e voli. Il sistema viene usato per prenotare i voli per i passeggeri e recuperare le informazioni relative ai passeggeri che hanno una prenotazione esistente su un volo. Quale tipo di database viene usato con maggiore probabilità per questo sistema?

3.

Un'applicazione di viaggio analizza le tendenze dei voli tramite l'inserimento dei dati dei passeggeri di tutto il mondo per fornire ad agenti di viaggio e tour operator internazionali informazioni sulle tendenze nel turismo. Quale tipo di sistema di database sottostante è più probabile che venga usato per questa applicazione?