1. PARTITIONING
AP CAMP 9 Ottobre 2010
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 1
2. Agenda
Cos'è il partitioning
Ereditarietà
Rules
Triggers
Metodi per eseguire il partitioning
Partition setup
Partition table explain plain
Tablespace
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 2
3. Ereditarietà (cenni)
PostgreSQL implementa l'ereditarietà di tabella
Keyword per usufruire dell'ereditarietà : INHERITS
apcamp=# CREATE TABLE citta( nome text, popolazione float, altitudine int4);
CREATE TABLE
apcamp=# create table capitali ( stato char(2) ) INHERITS (citta);
CREATE TABLE
apcamp=# d citta Apcamp=# d capitali
Table "public.citta" Table "public.capitali"
Column | Type | Modifiers Column | Type | Modifiers
-------------+------------------+----------- -------------+------------------+-----------
nome | text | nome | text |
popolazione | double precision | popolazione | double precision |
altitudine | integer | altitudine | integer |
Number of child tables: 1 (Use d+ to list them.) stato | character(2) |
Inherits: citta
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 3
4. Ereditarietà
Alcuni esempi:
apcamp=# insert into citta (nome,popolazione,altitudine)values ('Alba Adriatica',10000,0);
INSERT 0 1
apcamp=# insert into capitali (nome,popolazione,altitudine,stato)values
('Roma',1000000,0,'IT');
INSERT 0 1
apcamp=# select * from citta;
nome | popolazione | altitudine
----------------+-------------+------------
Alba Adriatica | 10000 | 0
Roma | 1000000 | 0
(2 rows)
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 4
5. Ereditarietà (cenni)
Clausola ONLY : ritorna i dati solo dalla tabella
specificata
apcamp=# select * from only citta; apcamp=# select * from only capitali;
nome | popolazione | altitudine nome | popolazione | altitudine | stato
----------------+-------------+------------ ------+-------------+------------+-------
Alba Adriatica | 10000 | 0 Roma | 1000000 | 0 | IT
(1 row) (1 row)
apcamp=# select * from capitali;
nome | popolazione | altitudine | stato
------+-------------+------------+-------
Roma | 1000000 | 0 | IT
(1 row)
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 5
6. Ereditarietà (cenni)
ATTENZIONE : Con i comandi INSERT o COPY
l'ereditarietà non propaga automaticamente i dati
alle altre tabelle dell'albero genealogico
apcamp=# insert into citta (nome,popolazione,altitudine,stato)values
('Roma',1000000,0,'IT');
ERROR: column "stato" of relation "citta" does not exist
LINE 1: insert into citta (nome,popolazione,altitudine,stato)values ...
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 6
7. Rules (cenni)
Sintassi :
CREATE [ OR REPLACE ] RULE name AS ON event
TO table [ WHERE condition ]
DO [ ALSO | INSTEAD ] { NOTHING | command | ( command ; command ... ) }
Modifica l'azione di un evento
Gli eventi modificabili sono INSERT,DELETE,UPDATE
E' possibile far partire azioni al posto di quelle di default o in
concomitanza con quelle di default.
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 7
8. Rules (cenni)
Esempio:
apcamp=# create table errori_capitali ( stato char(2) ) INHERITS (citta);
CREATE TABLE
apcamp=# create or replace rule my_rule as on insert to capitali where
(popolazione < 0) do instead insert into errori_capitali
(nome,popolazione,altitudine,stato) values
(NEW.nome,NEW.popolazione,NEW.altitudine,NEW.stato);
CREATE RULE
apcamp=# insert into capitali (nome,popolazione,altitudine,stato) values ('Parigi','-
10000',200,'FR');
INSERT 0 0
apcamp=# SELECT * from errori_capitali ;
nome | popolazione | altitudine | stato
--------+-------------+------------+-------
Parigi | -10000 | 200 | FR
(1 row)
apcamp=#
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 8
9. Rules (cenni)
Ogni volta che inseriamo un record il cui campo
popolazione sia < 0, La rule, fa si che questo record
non venga inserito nella tabella capitali ma in quella
errori_capitali
apcamp=# create or replace rule my_rule as on insert to capitali where
(popolazione < 0) do instead insert into errori_capitali
(nome,popolazione,altitudine,stato) values
(NEW.nome,NEW.popolazione,NEW.altitudine,NEW.stato);
PostgreSQL gestisce le rules prima dei triggers
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 9
10. Triggers (cenni)
E' un gestore complesso di eventi
NEW è la variabile che contiene il nuovo valore del
record;
Schema classico :
Evento
Azione
Insert, Update, Delete Trigger Funzione Trigger
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 10
11. Triggers (cenni)
Creazione della funzione che viene chiamata dal trigger
CREATE OR REPLACE function f_trigger() RETURNS trigger
as $$
BEGIN
.........
RETURN ......
END;
$$
language plpgsql;
Creazione del Trigger
CREATE TRIGGER miotrigger BEFORE INSERT ON citta FOR
EACH ROW EXECUTE PROCEDURE f_trigger();
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 11
12. Trigger (cenni)
Eseguiamo una procedura fatta prima con le rules
utilizzando un trigger:
apcamp=# SELECT * from errori_capitali ;
nome | popolazione | altitudine | stato
--------+-------------+------------+-------
Parigi | -10000 | 200 | FR
apcamp=# insert into citta (nome,popolazione,altitudine)
values ('Milano','-10000',200);
La rule fatta agisce INSERT 0 1
solo sulla tabella
apcamp=# select * from only citta;
capitali non sulla
tabella città nome | popolazione | altitudine
----------------+-------------+------------
Alba Adriatica | 10000 | 0
Milano | -10000 | 200
(2 rows)
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 12
13. Trigger (cenni)
CREATE OR REPLACE function f_trigger() RETURNS trigger
as $$
BEGIN
IF NEW.popolazione < 0 THEN
insert into errori_capitali (nome,popolazione,altitudine)
values (NEW.nome,NEW.popolazione,NEW.altitudine); Funzione chiamata
dal Trigger
END IF;
RETURN NULL;
END;
$$
language plpgsql;
Creazione del
CREATE TRIGGER miotrigger BEFORE INSERT ON citta FOR
EACH ROW EXECUTE PROCEDURE f_trigger(); Trigger
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 13
14. Trigger (cenni)
apcamp=# insert into citta (nome,popolazione,altitudine) values ('Palermo','-10000',200);
INSERT 0 0
apcamp=# select * from only citta;
nome | popolazione | altitudine
----------------+-------------+------------
Alba Adriatica | 10000 | 0
Milano | -10000 | 200
(2 rows)
apcamp=# select * from errori_capitali;
nome | popolazione | altitudine | stato
---------+-------------+------------+-------
Parigi | -10000 | 200 | FR
Palermo | -10000 | 200 |
(2 rows)
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 14
15. Trigger (cenni)
Schema riassuntivo
Rule
città
Errori_capitali
Trigger
capitali
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 15
16. Domande ????????
Ancora Vivi?
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 16
17. Cos'è il partitioning?
Partitioning è dividere una tabella con tanti record in
parti più piccole
Benefici:
Aumento delle prestazioni di ricerca e aggiornamento
Maggiore facilità nel migrare i dati della tabella su supporti
di storage più economici.
Tabella originaria
Q1 Q2 Q3 Q4
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 17
18. Overview
Partitioning significa dividere in piccole tabelle i contenuto di
una tabella di grande dimensione
Le perfomance possono essere incrementate drasticamente
per certi tipi di ricerche .La performance di update vengono
incrementate.
Gli indici possono entrare in memoria perchè di più piccola
dimensione
Alle volte le operazioni di delete possono equivalere
semplicemente con il rimuovere una delle partizioni
I dati posso essere passati su supporti più piccoli quindi più
economici e/o più veloci
Postgresql realizza il partitioning attraverso l'ereditarietà delle
tabelle. Ogni partizione deve essere creata come una tabella
figlia di una singola tabella madre. La tabella madre esiste
solo per rapprsentare il dataset ed è normalmente vuota.
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 18
19. Metodi per il partitioning
Range Partitioning
Le partizioni sono definite attraverso dei vincoli sulla
chiave primaria e non devono essere presenti
sovrapposizioni o buchi.
List Partitioning
Ogni valore della chiave primaria viene specificato in una
lista
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 19
20. Partitioning Setup
Creare la master table (tabella madre)
Questa tabella non conterrà i dati, definirà solamente i
vincoli che verranno applicati a tutte le partizioni.
Creare le tabelle figlie attraverso l'ereditarietà con la
tabella master
Aggiungere i vincoli nella tabella figlia per definire i
vincoli attraverso i quali i valori chiave vengono
accettati
Alcuni esempi: check (x = 1)
Check (provincia in ('MI','TO','BO'))
Check (id > 100 and id < 200)
Verificare che non ci siano sovrappposizioni di
valori nelle tabelle figlie
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 20
21. Partitioning Setup
Creare gli indici necessari in ogni tabella figlia
Definire le regole o i trigger per ridirigere i dati dalla
tabella master verso la tabella figlia appropriata.
Assicurarsi che constraint_exclusion in
postgresql.con sia impostato su true
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 21
23. Partioned table explain plan
explain SELECT * from mov_mag where campo1 = 'val1' and campo2 =
'val2';
QUERY PLAN
--------------------------------------------------------------------------------------------
Result (cost=0.00..29.83 rows=2 width=80)
-> Append (cost=0.00..29.83 rows=2 width=80)
-> Seq Scan on mov_mag (cost=0.00..21.55 rows=1 width=76)
Filter: ((campo1 = 'val1'::bpchar) AND ((campo2)::text =
'val2'::text))
-> Index Scan using citidx1 on mov_mag_2008 mov_mag
(cost=0.00..8.28 rows=1 width=80)
Index Cond: ((campo2)::text = 'val2'::text)
Filter: ("campo1" = 'val1'::bpchar)
(7 rows)
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 23
24. Creazione Master Table
CREATE TABLE vendite (
id INTEGER NOT NULL,
data_vendita DATE,
somma NUMERIC(9,2)
);
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 24
25. Creazione delle tabelle figlie
CREATE TABLE vendite_08q1 (
CHECK (data_vendita >= DATE '2008-01-01' AND
data_vendita < DATE '2008-04-01' )
) INHERITS (vendite);
CREATE TABLE vendite_08q2 (
CHECK (data_vendita >= DATE '2008-04-01' AND
data_vendita < DATE '2008-07-01' )
) INHERITS (vendite);
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 25
26. Creazione delle tabelle figlie
CREATE TABLE vendite_08q3 (
CHECK (data_vendita >= DATE '2008-07-01' AND
data_vendita < DATE '2008-10-01' )
) INHERITS (vendite);
CREATE TABLE vendite_08q4 (
CHECK (data_vendita >= DATE '2008-10-01' AND
data_vendita < DATE '2009-01-01' )
) INHERITS (vendite);
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 26
27. Creazione degli indici
● CREATE INDEX vendite_08q1_data_vendita on
vendite_08q1 (data_vendita);
● CREATE INDEX vendite_08q2_data_vendita on
vendite_08q2 (data_vendita);
● CREATE INDEX vendite_08q3_data_vendita on
vendite_08q3 (data_vendita);
● CREATE INDEX vendite_08q4_data_vendita on
vendite_08q4 (data_vendita);
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 27
28. Trigger o Rules?
Triggers
o Rules ?
Possiamo ora eseguire la suddivisione dei dati
utilizzando Triggers o Rules
Le Rules vengono gestite prima dei trigger
I trigger consentono una gestione più approfondita
degli eventi
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 28
29. Creazione delle RULES
CREATE RULE inserimento_vendita_08q1 AS
ON INSERT TO vendite WHERE
(data_vendita >= DATE '2008-01-01' AND
data_vendita < DATE '2008-04-01')
DO INSTEAD
INSERT INTO vendite_08q1(NEW.
id,NEW.data_vendita,NEW.somma);
STESSA COSA PER LE ALTRE TABELLE FIGLIE
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 29
30. CREAZIONE DEL TRIGGER
CREATE OR REPLACE function f_trigger() RETURNS
trigger
as $$
begin
IF
NEW.data_vendita >= DATE '2008-01-01'
AND NEW.data_vendita < DATE '2008-04-01' THEN
INSERT INTO vendite_08q1 values
(NEW.id,NEW.data_vendita,NEW.somma);
ELSIF
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 30
31. CREAZIONE DEL TRIGGER
NEW.data_vendita >= DATE '2008-04-01'
AND NEW.data_vendita < DATE '2008-07-01' THEN
INSERT INTO vendite_08q2 values
(NEW.id,NEW.data_vendita,NEW.somma);
ELSIF
......
END IF;
RETURN NULL;
END;
$$
language plpgsql;
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 31
32. CREAZIONE DEL TRIGGER
CREATE TRIGGER miotrigger BEFORE INSERT
ON vendite FOR EACH ROW EXECUTE
PROCEDURE f_trigger();
A questo punto la procedura di partitioning è terminata
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 32
33. Partitioning : manuntenzione
Esistono diversi modi per rimuovere una partizione
DROP TABLE nome_partizione
E' preferibile di più però ALTER TABLE
nome_partizione_NO INHERIT master_table
Se invece vogliamo cancellare la master_table e
tutte le sue partizioni :
DROP TABLE master_table CASCADE
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 33
34. CAVEATS
Non c'è un metodo per verificare che tutti i vincoli
imposti siano mutuamente esclusivi
Non c'è un metodo per specificare che nessuna riga
deve essere inserita nella master_table → senza
TRIGGER ovviamente
Dal momento che la master_table non contiene dati
non è possibile assegnare alcuna foreign key alla
master_table
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 34
35. PARTITIONING
Cos'è il partitioning
Ereditarietà
Rules
Triggers
Metodi per eseguire il partitioning
Partition setup
Partition table explain plain
Tablespace
09/10/10 /Users/sscotty71/Desktop/partitioning_apcamp.odp page 35