Scurta descriere:
Partiționarea presupune descompunerea tabelelor ori a indecșilor foarte mari în „bucăți” mai mici și mai ușor de gestionat, numite partiții. Interogările SQL și declarațiile DML nu trebuie să fie modificate pentru a accesa tabelele partiționate.
De regulă când dorim să partiționăm o tabelă vom specifica acest lucru în definiția tabelei, asta presupune să știm de la început că vom avea un volum mare de înregistrări în această tabela. Totuși ce putem face dacă nu am definit de la început partițiile iar acum tabela este populata cu multe înregistrări? Sigur că o posibilitate ar fi să exportam tabela, să-i facem drop, să o recreăm folosind partițiile după care sa importam datele, dar va imaginați ca acesta operațiune este foarte costisitoare ca timp iar în plus nu poate fi realizata online. Eu prefer varianta mai simpla, pe care o voi descrie mai jos:
1. Primul pas, vom defini o tabela de test t1, aceasta trebuie să conțină o cheie primară
CREATE TABLE "TEST"."T1"
(
"ID" NUMBER,
"C1" NUMBER,
CONSTRAINT "ID" PRIMARY KEY ("ID"));
Table created.
insert into t1
select rownum id,
trunc(dbms_random.value(1,1e6)) c1
from dual
connect by
level <= 1e4;
10000 rows created.
2. verificăm dacă tabela t1 poate fi redefinită online:
exec dbms_redefinition.can_redef_table('test', 't1')
3. creăm o tablă cu aceeași structură ca cea a tabelei t1, doar că aceasta va fi partiționată.
CREATE TABLE TEST.temp
(
"ID" NUMBER,
"C1" NUMBER
)
Partition by range(ID)
(
partition P1 values less than (2000),
partition PMAX values less than (maxvalue)
);
4. inițiem procesul de redefinire cu ajutorul procedurii dbms_redefinition.start_redef_table
exec dbms_redefinition.start_redef_table('test', 't1', 'temp');
5. copiem dependințele
declare
erori pls_integer := 0;
BEGIN
dbms_redefinition.copy_table_dependents('test', 't1', 'temp', 1, TRUE, TRUE, TRUE , FALSE, erori);
dbms_output.put_line('erori:= ' || to_char(erori));
END;
6. finalizam procesul de redefinire apelând procedura dbms_redefinition.finish_redef_table
exec dbms_redefinition.finish_redef_table('test', 't1', 'temp');
7. în acest moment, dacă toți pașii s-au realizat cu succes, atunci tabela t1 este partiționată, dupa ce verificam ca totul este în regula ștergem tabela temporara
SELECT partitioned FROM user_tables WHERE table_name = 'T1';
PAR
---
YES
SELECT count(*) FROM test.t1;
COUNT(*)
----------
10000
DROP TABLE test.temp
Am testat operatia de partitionare si a decurs cu succes. Numai ca select-ul SELECT partitioned FROM user_tables WHERE table_name = ‘T1′; nu a adus nici o inregistrare. Daca m-am dus pe tabela si descrierea acesteia (in TOAD de ex.) am obs. partitia creata. Mentionez ca am rulat select-ul si cu filtrul de partitioned=’YES’.
Daca „SELECT partitioned FROM user_tables WHERE table_name = ‘T1′;” nu a întors nici o înregistrare este posibil ca utilizatorul cu care ești conectat sa nu fie owner-ul tabelei T1. Încearcă sa cauți în dba_tables (trebuie sa ai drepturi pe acest view).