Corso
Che tu stia creando app orientate al cliente o gestendo pipeline analitiche complesse, una cosa è chiara: il modo in cui archivi e accedi ai dati può determinare il successo o il fallimento delle prestazioni.
Ho visto in prima persona quanto più fluidi siano i sistemi quando i dati sono strutturati con cura, ed è qui che entra in gioco il partizionamento dei dati. È una di quelle tecniche che può migliorare drasticamente la velocità delle query, l'efficienza di archiviazione e la scalabilità.
In questo post spiegherò cos'è il data partitioning, i diversi tipi disponibili e le best practice che ho imparato lungo il percorso.
Che cos'è il data partitioning?
Il data partitioning è una tecnica per suddividere grandi dataset in porzioni più piccole e gestibili chiamate partizioni. Ogni partizione contiene un sottoinsieme di dati ed è distribuita su più nodi o server. Queste partizioni possono essere archiviate, interrogate e gestite come tabelle individuali, pur appartenendo logicamente allo stesso dataset.
Il partizionamento dei dati migliora le prestazioni e la scalabilità del database. Per esempio, cercare un dato nell'intera tabella richiede più tempo e risorse rispetto a cercarlo in una partizione specifica. Ecco perché i dati vengono archiviati come partizioni.
Tipi di data partitioning
Il partizionamento dei dati comprende vari tipi, ognuno con una strategia e benefici specifici. In questa sezione tratto i tipi più comuni.
Partizionamento orizzontale
Invece di archiviare tutti i dati in un'unica tabella, il partizionamento orizzontale suddivide i dati per righe, il che significa che insiemi diversi di righe vengono archiviati come partizioni.
Tutte le partizioni del partizionamento orizzontale contengono lo stesso set di colonne ma gruppi diversi di righe.
- Esempio: Poniamo di avere un dataset meteo per più stati in tre diversi paesi. Puoi partizionarlo in tre tabelle suddividendo le righe per ciascun paese.
|
Temperatura |
Stato |
Paese |
Stagione |
|
-30° F |
Alaska |
USA |
Inverno |
|
48.2° F |
Queensland |
Australia |
Estate |
|
100° F |
Andhra Pradesh |
India |
Estate |
|
35° F |
California |
USA |
Inverno |
|
96° F |
Texas |
USA |
Estate |
|
62° F |
Tasmania |
Australia |
Inverno |
Partizionamento orizzontale per paese:
|
Temperatura |
Stato |
Paese |
Stagione |
|
-30° F |
Alaska |
USA |
Inverno |
|
35° F |
California |
USA |
Inverno |
|
35° F |
California |
USA |
Inverno |
|
Temperatura |
Stato |
Paese |
Stagione |
|
48.2° F |
Queensland |
Australia |
Estate |
|
62° F |
Tasmania |
Australia |
Inverno |
|
Temperatura |
Stato |
Paese |
Stagione |
|
100° F |
Andhra Pradesh |
India |
Estate |
Partizionamento verticale
Il partizionamento verticale divide i dati per colonne, così ogni partizione contiene lo stesso numero di righe ma meno colonne.
La chiave di partizione o la colonna primaria sarà presente in ogni partizione, mantenendo la relazione logica.
Il partizionamento verticale è diffuso quando si vogliono conservare informazioni sensibili separatamente dai dati ordinari. Consente di salvare le colonne sensibili in una partizione e i dati standard in un'altra.
Un altro caso d'uso comune è raggruppare in una partizione le colonne aggiornate frequentemente e in un'altra le restanti.
- Esempio: Se le colonne numero di telefono e stipendio dei dipendenti nella tabella seguente sono riservate, partizioniamo la tabella di conseguenza.
|
Emp_id |
Emp_name |
Designation |
Emp_email |
Emp_phone |
Emp_salary |
|
z0yu9h |
Alex |
Data scientist |
alex@yoho.com |
+101 890 456 |
250K |
|
f8o5pj |
Adam |
Data engineer |
adam@prodgy.com |
+630 789 365 |
230K |
|
z006yu |
Matt |
Data analyst |
matt@oltk.com |
+857 342 937 |
166K |
|
a6u895 |
Elina |
Ops engineer |
elina@wal.com |
+892 494 782 |
190K |
|
g68w90 |
Joseph |
Software engineer |
joseph@yoho.com |
+852 603 389 |
210K |
Emp_id è l'identificatore univoco nella tabella sopra, quindi tutte le partizioni lo includono.
Partizione 1:
|
Emp_id |
Emp_name |
Designation |
Emp_email |
|
z0yu9h |
Alex |
Data scientist |
alex@yoho.com |
|
f8o5pj |
Adam |
Data engineer |
adam@prodgy.com |
|
z006yu |
Matt |
Data analyst |
matt@oltk.com |
|
a6u895 |
Elina |
Ops engineer |
elina@wal.com |
|
g68w90 |
Joseph |
Software engineer |
joseph@yoho.com |
Partizione 2:
|
Emp_id |
Emp_phone |
Emp_salary |
|
z0yu9h |
+101 890 456 |
250K |
|
f8o5pj |
+630 789 365 |
230K |
|
z006yu |
+857 342 937 |
166K |
|
a6u895 |
+892 494 782 |
190K |
|
g68w90 |
+852 603 389 |
210K |
Partizionamento per intervalli
Il partizionamento per intervalli suddivide i dati in base a un intervallo di valori per una determinata colonna.
In genere, ogni partizione ha un limite inferiore e uno superiore per la colonna chiave, e un record che rientra in questo intervallo viene assegnato a quella partizione.
- Esempio: Poniamo che i dati di vendita siano disponibili dal 2021 al 2023. Possiamo partizionarli per anno in modo che le vendite dal 2021 al 2022 ricadano in una partizione e dal 2022 al 2023 in un'altra.
|
Product_id |
Data |
Profitto |
|
z0yu9h |
2021-03-17 |
$100K |
|
f8o5pj |
2022-04-04 |
$234K |
|
z006yu |
2022-09-13 |
$789K |
|
a6u895 |
2021-07-23 |
$237K |
|
g68w90 |
2022-02-26 |
$2345K |
Partizione 1:
|
product_id |
Data |
Profitto |
|
z0yu9h |
2021-03-17 |
$100K |
|
a6u895 |
2021-07-23 |
$237K |
Partizione 2:
|
product_id |
Data |
Profitto |
|
f8o5pj |
2022-04-04 |
$234K |
|
z006yu |
2022-09-13 |
$789K |
Partizionamento per hash
Si applica una funzione di hash alla chiave di partizione e l'output determina in quale partizione archiviare ciascun record. Con questa tecnica, il numero di partizioni è deciso in anticipo.
Il resto ottenuto dividendo il valore di hash per il numero di partizioni determina in quale partizione archiviare quello specifico record. Vediamolo con un esempio:
- Esempio: Supponiamo che, per il prodotto con ID
z0yu9h,hash(‘z0yu9h’) = 101e numero di partizioni = 4, allora 101%4 = 1. Quindi, questo record viene archiviato nella prima partizione.
In questo modo, si calcolano i valori di hash per la colonna chiave di partizione, li si divide per il numero di partizioni e il risultato determina la partizione finale.
Partizionamento per lista
La procedura è simile al partizionamento per intervalli, ma invece di suddividere i dati per un intervallo di valori, il partizionamento per lista divide i dati in base a un set predefinito di valori.
Riprendiamo come esempio la tabella delle temperature.
|
Temperatura |
Stato |
Paese |
Stagione |
|
30° F |
Alaska |
USA |
Inverno |
|
48.2° F |
Queensland |
Australia |
Estate |
|
100° F |
Andhra Pradesh |
India |
Estate |
|
35° F |
California |
USA |
Inverno |
|
96° F |
Texas |
USA |
Estate |
|
62° F |
Tasmania |
Australia |
Inverno |
Nei dati sopra, la colonna "Stagione" contiene una lista di valori [‘winter’, ‘summer’]. Quindi, il partizionamento per lista sulla stagione appare così:
Partizione 1:
|
Temperatura |
Stato |
Paese |
Stagione |
|
30° F |
Alaska |
USA |
Inverno |
|
35° F |
California |
USA |
Inverno |
|
62° F |
Tasmania |
Australia |
Inverno |
Partizione 2:
|
Temperatura |
Stato |
Paese |
Stagione |
|
48.2° F |
Queensland |
Australia |
Estate |
|
100° F |
Andhra Pradesh |
India |
Estate |
|
96° F |
Texas |
USA |
Estate |
Partizionamento composito
Una partizione composita è una combinazione di due tecniche di partizionamento. Una tabella viene prima suddivisa utilizzando una strategia e ciascuna partizione viene ulteriormente suddivisa utilizzando un'altra tecnica.
Le strategie di partizionamento sono spesso trattate nei colloqui tecnici: vedi le migliori domande di colloquio per DBA per il 2025.
Casi d'uso del data partitioning
Ora che abbiamo valutato i diversi tipi di strategie di partizionamento, vediamo quando il partizionamento dei dati è utile.
Database distribuiti
I sistemi distribuiti sono insiemi di nodi fisicamente posizionati su server separati ma collegati tramite una rete. Esempi includono Apache Cassandra, Amazon DynamoDB e Google Bigtable.
Questi sistemi utilizzano internamente il partizionamento dei dati per organizzare e distribuire i dati tra i nodi.
Operazioni OLAP
OLAP rappresenta i dati multidimensionali come cubi, consentendo agli utenti di esplorare i dati da angolazioni diverse. Sebbene questi cubi rappresentino dati pre-aggregati, i dati sottostanti sono comunque vasti, quindi le query richiedono un'ulteriore ottimizzazione tramite il partizionamento dei dati.
Ad esempio, applicare il cube partitioning (una tecnica di partizionamento dei dati) divide i dati in cubi più piccoli in base a criteri specifici. Quando esegui una query sui dati, la ricerca viene effettuata su un cubo specifico saltando quelli non pertinenti, riducendo le operazioni di I/O.
Allo stesso modo, è possibile applicare il partizionamento per dimensione per suddividere i dati per livello, gerarchia o colonna.
Gestione dei log
I log contengono informazioni su eventi, transazioni e operazioni che avvengono in un sistema. Si usano per tracciare errori, bug, edge case e persino messaggi di successo.
Il partizionamento dei log accelera il processo di debug e ti fornisce più rapidamente le informazioni necessarie. Per esempio, se hai partizionato i log per periodo di tempo, puoi recuperarli facilmente per data, settimana, mese o anno.
Pipeline di machine learning
Nei casi d'uso di machine learning, i dati vengono suddivisi in set di training, validazione e test. Questo approccio assicura che le informazioni del set di test non vengano rivelate al modello durante l'addestramento, evitando l'overfitting.
Inoltre, se i dati di training sono enormi, una singola macchina non può elaborarli e alimentarli interamente a un modello. Quindi, i dati vengono divisi in blocchi e forniti al modello tramite partizionamento dei dati.
Strumenti per il data partitioning
Il partizionamento dei dati può essere implementato sia in database SQL che NoSQL. Parliamone in questa sezione.
Database SQL
PostgreSQL
PostgreSQL offre supporto nativo per il partizionamento per intervalli, per lista e per hash. Ad esempio, la query seguente crea una partizione per ogni anno per accedere in modo efficiente ai profitti e alle vendite totali per ogni anno fiscale.
CREATE TABLE sales(
city_id int not null,
sales_year date not null,
total_sales int,
sales_profits int
) PARTITION BY RANGE (sales_year);
MySQL
MySQL supporta diversi tipi di partizionamento orizzontale, come range, list, hash e key partitioning. Al momento (versione 8.4), non supporta il partizionamento verticale.
La query MySQL seguente partiziona i dati dei dipendenti in tre gruppi, p1, p2 e p3, in base alle loro date di assunzione. Tutti i dipendenti assunti prima del 2000 rientrano nella partizione p1. I dipendenti assunti tra il 2000 e il 2010 rientrano nella partizione p2, e quelli assunti tra il 2010 e il 2020 nella partizione p3.
CREATE TABLE employee(
firstname VARCHAR(25) NOT NULL,
username VARCHAR(16) NOT NULL,
email VARCHAR(35),
salary INT,
joined DATE NOT NULL
)
PARTITION BY RANGE( YEAR(joined) ) (
PARTITION p1 VALUES LESS THAN (2000),
PARTITION p2 VALUES LESS THAN (2010),
PARTITION p3 VALUES LESS THAN (2020)
);
Microsoft SQL Server
SQL Server offre funzionalità di partizionamento tramite funzioni di partizione e schemi di partizione. Una funzione di partizione specifica come vengono suddivisi i dati, mentre lo schema di partizione determina il filegroup in cui verrà archiviata la partizione.
Nelle query seguenti:
- Nome funzione:
sales_by_year - Nome schema:
sales_filegroup - Nomi filegroup:
fg01,fg02,fg03,fg04
Funzione di partizione:
create partition function sales_by_year (date)
as range right for values
('2024-01-01', '2024-02-01', '2024-03-01', ‘2024-04-01’);
Schema di partizione:
CREATE PARTITION SCHEME sales_filegroup
AS PARTITION sales_by_year
TO (fg01, fg02, fg03, fg04);
Qui, i file archiviano i dati come segue:
fg01- date precedenti a "2024-01-01",fg02- da "2024-01-01" a "2024-01-31"fg03- da "2024-02-01" a "2024-02-29"fg04- da "2024-03-01" a "2024-03-31"
Poiché abbiamo specificato range right nella query, ogni data limite è inclusa nella partizione successiva.
Se stai usando SQL Server, questo tutorial su SQL Server illustra i concetti chiave e gli strumenti per gestire i dati partizionati. Per un percorso di apprendimento strutturato, il percorso SQL Server Fundamentals introduce le funzionalità di base necessarie per costruire database SQL ad alte prestazioni.
Database NoSQL
Amazon DynamoDB
DynamoDB gestisce automaticamente il partizionamento internamente. Quando scrivi un elemento in una tabella DynamoDB, questo passa attraverso un request router. Il router analizza la chiave di partizione e applica una funzione di hash. L'output della funzione di hash determina la partizione specifica in cui verrà archiviato il record.
L'intero processo è automatizzato in DynamoDB, quindi l'utente non deve preoccuparsi della funzione di hash o di come vengono gestite le partizioni.
Mongodb
MongoDB distribuisce i dati tra i server tramite il concetto di sharding. I dati vengono partizionati in base a una shard key, che deve essere scelta con attenzione per evitare distribuzioni non uniformi.
In genere, la shard key dovrebbe avere alta cardinalità ed essere la colonna più usata nelle query. Queste domande di colloquio su MongoDB coprono quasi tutti gli argomenti importanti, incluso lo sharding.
Apache Cassandra
Cassandra partitioner è un algoritmo di hashing che determina quale nodo in un cluster debba archiviare una determinata partizione. La chiave di partizione viene analizzata dall'algoritmo per produrre un token. Questo token viene poi confrontato con i valori di token assegnati ai nodi. Infine, i dati vengono archiviati nel nodo che corrisponde al token.
Gli algoritmi di partizione comuni includono Murmur3Partitioner, RandomPartitioner e ByteOrderedPartitioner.
Come implementare il data partitioning?
Ora vediamo i passaggi necessari per implementare correttamente il partizionamento dei dati.
Passo 1: Comprendere dati e pattern di accesso
Valuta a fondo come la tua applicazione interroga il database, quali dati sono spesso accessibili, la dimensione dei dati e i colli di bottiglia delle prestazioni. Queste informazioni ti aiuteranno a definire obiettivi chiari per il partizionamento e a identificare le colonne chiave spesso coinvolte nelle operazioni sui dati.
Passo 2: Scegli una tecnica di partizionamento
Abbiamo già visto le tecniche comuni, ecco come decidere tra esse:
- Partizionamento orizzontale: Quando hai milioni o miliardi di righe che verrebbero archiviate in un'unica tabella causando problemi di memoria, dovresti scegliere il partizionamento orizzontale. Archivia set diversi di righe in tabelle diverse.
- Partizionamento verticale: Se un gruppo di colonne è spesso accessibile e altre sono interrogate occasionalmente, puoi implementare il partizionamento verticale per archiviare le colonne separatamente in base ai pattern di accesso.
- Approccio ibrido: Quando hai dataset molto grandi che richiedono di ridurre il numero di righe ottimizzando al contempo le query per un sottoinsieme di colonne, dovresti scegliere un approccio ibrido. Combina i vantaggi del partizionamento orizzontale e verticale.
Passo 3: Crea le partizioni
Di seguito un esempio di query SQL per creare partizioni utilizzando il partizionamento per hash.
CREATE TABLE employees (
emp_id INT NOT NULL,
name VARCHAR(30),
hired DATE NOT NULL DEFAULT '2024-01-01',
job_id INT,
location_id INT
)
PARTITION BY HASH(location_id)
PARTITIONS 4;
Nel codice sopra, la colonna "location_id" viene passata alla funzione di hash e l'output determina la partizione a cui assegnare il record. La riga di codice partitions 4 specifica il numero totale di partizioni da creare.
Aggiungi ai preferiti questo comodo SQL Basics Cheat Sheet per consultare la sintassi SQL di base mentre implementi le partizioni.
Passo 4: Monitora e ottimizza le partizioni
- Monitora continuamente le operazioni sui dati e assicurati che le partizioni siano aggiornate e valide.
- Man mano che l'applicazione scala, potresti dover aggiungere altre partizioni o scegliere un approccio diverso, come una partizione ibrida, per soddisfare le nuove esigenze.
- Assicurati che dimensione e strategia delle partizioni favoriscano le operazioni più frequenti eseguite sul database.
- Garantisci una distribuzione uniforme dei dati tra le partizioni; in caso contrario, potresti doverle ribilanciare.
Sfide e considerazioni per il data partitioning
Le ottimizzazioni comportano compromessi e sfide, come in tutto il mondo del software. Ecco quelle da considerare:
- Skew delle partizioni: lo skew delle partizioni significa che alcune partizioni ricevono più dati e lavoro di elaborazione mentre altre restano spesso inattive. Per evitarlo, scegli la giusta chiave di partizione e una strategia che distribuisca uniformemente i dati in tutte le partizioni.
- Overhead di manutenzione: Con la crescita dei dati, devi rivalutare le strategie di partizionamento esistenti e assicurarti che siano adatte ai dati attuali. In caso contrario, potresti dover ripartizionare o unire partizioni.
- Migrazioni dei dati: nel caso di migrazione dei dati verso una nuova architettura, serve particolare attenzione per garantire che le partizioni siano compatibili con il nuovo ambiente. Inoltre, spostare i dati tra partizioni comporta complessità come la gestione della consistenza dei dati tra shard.
- Ripida curva di apprendimento: il partizionamento dei dati aggiunge complessità a un sistema o a un'architettura cloud. Non sono banali da interrogare, migrare o analizzare, con una curva di apprendimento ripida per i principianti.
Best practice per il data partitioning
Come vedi, il partizionamento dei dati diventa complesso con l'aumentare del volume dei dati. Tuttavia, applicare queste pratiche assicurerà che il partizionamento migliori l'efficienza senza compromettere le prestazioni.
- Allinea le partizioni ai pattern di query: Scegliere la giusta strategia di partizionamento e la chiave di partizione può migliorare significativamente le prestazioni del database. Comprendi le operazioni sui dati e i pattern di query più comuni nel tuo database e seleziona una chiave di partizione frequentemente coinvolta nelle query garantendo al contempo una distribuzione uniforme dei dati.
- Monitora regolarmente: oggi le applicazioni sono dinamiche e in continua evoluzione con tendenze ed esigenze che cambiano. Pertanto, è importante monitorare regolarmente le partizioni per allinearle agli attuali pattern di accesso e ripartizionare quando necessario.
- Riduci l'overhead: gestire manualmente le partizioni su larga scala è complesso. Tuttavia, database NoSQL come Apache Cassandra e Amazon DynamoDB automatizzano il processo senza richiedere molto lavoro extra. Inoltre, alcuni strumenti di automazione adattano le partizioni man mano che i dati crescono, abilitando il ripartizionamento o l'unione delle partizioni secondo le tue necessità.
Conclusione
Un partizionamento efficace dei dati è fondamentale per mantenere prestazioni e scalabilità al crescere dei tuoi dati. Con la giusta strategia, puoi ridurre la latenza delle query, ottimizzare l'archiviazione e semplificare la manutenzione. È un passo pratico con un impatto misurabile.
Per approfondire come il partizionamento consente ai sistemi distribuiti di scalare, dai un'occhiata a questa guida sulle partizioni di Kafka. Per capire come le strutture relazionali influenzano le decisioni di partizionamento, inizia con questo corso sui database relazionali.
Srujana è una tech writer freelance con una laurea quadriennale in Informatica. Scrivere di vari argomenti, tra cui data science, cloud computing, sviluppo, programmazione, sicurezza e molti altri, le viene naturale. Ama la letteratura classica ed esplorare nuove destinazioni.


