Il celebre DBMS di Sun Microsystem, MySQL ha raggiunto a Giugno la versione 5.1. Tra le varie novità spicca la possibilità di poter partizionare le tabelle.
Cosè e a cosa serve
Il partizionamento consiste nel dividere una tabella logica in piu file fisici. I vantaggi sono ovvi: gestire tabelle enormi con più semplicità.
Possiamo esaminare un’anagrafe molto grossa… per esempio l’anagrafe cinese. Una tabella di 1.330.503.015 di righe, 80 byte ogni riga: ci troviamo difronte a un file di piu di 80Gb! Manipolare un file di queste dimensioni si potrebbe rilevare estremamente pesante e frustrante per l’utonto.
Soluzione piu ovvia sarebbe quella di dividere gli abitanti alfabeticamnete in 20 file diversi arrivando ad avere tabelle di circa 4Gb ogniuna. Molto piu comodo!
I tipi di partizionamento
Partitioning by Range
La divisione in questo primo caso avviene per suddivisione per intervallo. Ad esempio potremmo voler dividere le tabelle degli articoli di un blog a seconda dell’anno in cui sono stati scritti.
per creare questo tipo di tabella:
mysql> CREATE TABLE Articolo
-> {
-> id INT UNSIGNED NOT NULL,
-> …
-> …
-> data DATE NOT NULL,
-> …
-> PARTITION BY RANGE(YEAR(data)) <- diciamo a mysql quale tipo di partizione utilizzare e su che colonna
-> (
-> PARTITION PPAST VALUES LESS THEN (YEAR(NOW()), <- dividiamo quindi i dati a seconda dell’anno
-> PARTITION PNOW VALUES LESS THEN MAXVALUE,
-> )
-> }
per vedere i files possiamo quindi spostarci nella cartella dove è contenuto il DB e dare un ls
# cd /usr/local/myslq/data/test
# ls -l Articolo
-rw-rw—- […] […] […] Articolo.frm
-rw-rw—- […] […] […] Articolo.par
-rw-rw—- […] […] […] Articolo#P#PPAST.MYD
-rw-rw—- […] […] […] Articolo#P#PPAST.MYI
-rw-rw—- […] […] […] Articolo#P#PNOW.MYD
-rw-rw—- […] […] […] Articolo#P#PNOW.MYI
Partitioning by List
In questo caso invece di avere un range fornisco al DB una lista dettagliata di valori in cui voglio siano suddivisi.
mysql> CREATE TABLE Articolo
-> {
-> id INT UNSIGNED NOT NULL,
-> …
-> …
-> data DATE NOT NULL,
-> …
-> PARTITION BY LIST(YEAR(data))
-> (
-> PARTITION P2006 VALUES IN (2006),
-> PARTITION P2007 VALUES IN (2007),
-> PARTITION P2008 VALUES IN (2008)
-> )
-> }
Partitioning by hash e by key
Partizionare by range e by list può dare problemi di non omogeneità nelle tabelle: ad esempio posso aver fatto 1 articolo nel 2006 e 100 nel 2007 per poi arrivare a 1000 nel 2008.
Per ovviare al problema mysql ci propone di poter dividere automaticamente la tabella in piu partizioni.
mysql> CREATE TABLE part_hash
-> (colonna1 INT, colonna2 INT, colonna3 CHAR(10))
-> PARTITION BY HASH (colonna3) <- colonna su cui partizionare
-> PARTITIONS 5; <- numero di partizioni in cui dividere
mysql> CREATE TABLE part_key
(colonna1 INT, colonna2 INT, colonna3 CHAR(10))
-> PARTITION BY KEY() <- partiziona utilizzando la chiave come base su cui partizionare
-> PARTITIONS 5; <- numero di partizioni in cui dividere
Modificare le tabelle
Ovviamente MySQL ci da la possibilità di modificare le partizioni della tabella.
Aggiunta by range:
E’ possibile aggiungere una partizione solo se è l’ultima della lista: non posso aggiungere un intervallo tra due esistenti (piu avanti spiegherò come fare 😉 )
mysql> ALTER TABLE tabella1
-> ADD PARTITION (PARTITION p2008
-> VALUES LESS THEN (2008));
Aggiunta by list:
Anche in questo caso abbiamo una limitazione: non possiamo aggiungere valori che siano presenti in altre partizioni (ma mi pare piu che logico! )
mysql> ALTER TABLE tabella2
-> ADD PARTITION (PARTITION p5
-> VALUES IN (5, 4, 8));
Eliminare una partizione:
Molto semplice, ma attenzione: questo comando elimina i dati contenuti in tale partizione!
mysql> ALTER TABLE tabella1 DROP PARTITION p2008;
Riorganizzare le partizioni
Il tempo passa e ci accorgiamo che la suddivisione di partizioni iniziali non è propio ottimale, come fare?
mysql> ALTER TABLE utenti REORGANIZE PARTITION
-> p0 INTO (PARTITION p01 VALUES LESS THEN (2005),
-> PARTITION p02 VALUES LESS THEN (2006));
questo ci permette di “spezzare” in due la partizione. Per riunirle invece:
mysql> ALTER TABLE utenti REORGANIZE PARTITION
-> p01 ,p02 INTO (PARTITION p0 VALUES LESS THEN (2005));
in questo modo possiamo “rimettere in gioco” tutti i dati divisi nelle partizioni:
mysql> ALTER TABLE utenti REORGANIZE PARTITION
-> * INTO (
-> PARTITION p0 VALUES LESS THEN (2006),
-> PARTITION p1 VALUES LESS THEN (2007),
-> PARTITION p2 VALUES LESS THEN (2008),
-> PARTITION p3 VALUES LESS THEN (2009));
Conclusioni
Sicuramente questo sistema di partizioni renderà la vita molto piu semplice a chi si trova a dover combattere con una quantità esagerata di dati, permettendo piu veloci tempi di risposta all’utente finale.
Alla prossima.
Alessandro Lorenzi