Partitionierte Tabellen bei Oracle sind eigentlich toll. Außer wenn man später an neue Partitionen hinzufügen möchte. Dann wird einem wahrscheinlich der Oracle Fehler ORA-14074 begegnen:
CREATE TABLE test_part
(
MONAT NUMBER(8) NOT NULL,
WERT NUMBER(8)
)
PARTITION BY RANGE (Monat)
(
PARTITION P2006 VALUES LESS THAN (200700),
PARTITION P2007 VALUES LESS THAN (200800),
PARTITION PMAX VALUES LESS THAN (MAXVALUE)
);
So wird eine Tabelle angelegt, die anhand des Attributs Monat partitioniert wird. Damit liegen alle Daten, bei denen das Attribut Monat kleiner als 200700 ist in die Partition P2006 gespeichert, Werte kleiner als 200800 in der Partition P2007 und alle höheren Werte in der Partition PMAX.
Das ist vor allem dann sinnvoll, wenn man richtig viele Daten in der Tabelle speichern will. Über einen partitionierten Index kann man dann extrem effizient auf die Daten zugreifen, vorausgesetzt, man schränkt immer über den Partitionierungsschlüssel ein.
Sinnvollerweise könnte man die unterschiedlichen Partitionen auch noch in verschiedene Tablespaces legen, damit man zum Beispiel die Daten physisch besser auf dem Datenbankserver verteilen kann. Man kann auch selektiv Daten die älter als eine gewisse Zeit sind nur noch schreibgeschützt verfügbar machen.
Geben wir mal ein paar Testdaten ein:
INSERT INTO TEST_PART VALUES (200602, 1);
INSERT INTO TEST_PART VALUES (200702, 1);
INSERT INTO TEST_PART VALUES (200902, 1);
INSERT INTO TEST_PART VALUES (201002, 1);
INSERT INTO TEST_PART VALUES (201003, 1);
INSERT INTO TEST_PART VALUES (201004, 1);
INSERT INTO TEST_PART VALUES (201102, 1);
COMMIT;
In diesem Fall wird jetzt der erste Datensatz in der Partition P2006 gespeichert, der zweite in der Partition P2007 und der Rest in der Partition PMAX.
Wie man an diesem Beispiel sieht, und wie einem sicherlich auch oft passiert, werden die Partitionen vergessen und irgendwann merkt man, dass alle Daten nur noch in die Partition PMAX läuft, weil die Tabelle nun schon länger lebt als man ursprünglich mal geglaubt hat. Hier wäre es jetzt an der Zeit, mal die Partitionen für die Jahre 2008, 2009, 2010, 2011 und weitere anzulegen.
Bevor wir neue Partitionen anlegen, prüfen wir kurz, welches die aktuellen Grenzwerte für die Partitionen sind:
SELECT HIGH_VALUE
FROM USER_TAB_PARTITIONS
WHERE TABLE_NAME = 'TEST_PART';
HIGH_VALUE
----------
200700
200800
MAXVALUE
Nun könnte man einfach probieren, neue Partitionen anzulegen. Schließlich gibt es ja einen passenden ALTER Table Befehl:
ALTER TABLE TEST_PART
ADD PARTITION P2008
VALUES LESS THAN (200900);
Error at line 1
ORA-14074: partition bound must collate
higher than that of the last partition
Das bedeutet, man kann eigentlich nur Partitionen hinzufügen, die eine höhere Obergrenze haben, als bereits vorhanden sind. Dies ist aus zwei Gründen doof:
1) Man kann also keine Partitionen einfach zwischendrin erzeugen.
2) Als letzte Partition nutzen wir hier das Schlüsselwort MAXVALUE. Es wird schwierig werden, eine Obergrenze zu finden, die noch größer ist, als die maximal möglichen Werte.
Offensichtlich ist es nicht so einfach, Oracle davon zu überzeugen, neue Partitionen anzulegen. Es gibt aber einen einfach Trick, dennoch neue Partitionen anzulegen. Dazu müssen die vorhandenen Partitionen einfach nur aufgesplittet werden.
ALTER TABLE TEST_PART
SPLIT PARTITION PMAX AT (200900)
INTO (PARTITION P2008, PARTITION PMAX);
ALTER TABLE TEST_PART
SPLIT PARTITION PMAX AT (201000)
INTO (PARTITION P2009, PARTITION PMAX);
ALTER TABLE TEST_PART
SPLIT PARTITION PMAX AT (201100)
INTO (PARTITION P2010, PARTITION PMAX);
ALTER TABLE TEST_PART
SPLIT PARTITION PMAX AT (201200)
INTO (PARTITION P2011, PARTITION PMAX);
Jetzt prüfen wir noch einmal, ob die Partitionen auch korrekt angelegt wurden:
SELECT PARTITION_NAME,HIGH_VALUE
FROM USER_TAB_PARTITIONS
WHERE TABLE_NAME='TEST_PART'
ORDER BY 1;
PARTITION_NAME HIGH_VALUE
-------------- -----------
P2006 200700
P2007 200800
P2008 200900
P2009 201000
P2010 201100
P2011 201200
PMAX MAXVALUE
7 rows selected.
Das sieht doch gut aus. Außerdem können wir jetzt noch eine Partition rausgreifen, und alle Datensätze aus dieser Partition anzeigen lassen:
SELECT MONAT,COUNT(*)
FROM TEST_PART PARTITION (P2010)
GROUP BY mONAT
MONAT COUNT(*)
---------- ----------
201002 1
201003 1
201004 1
3 rows selected.
Linkdump:
[url]http://www.mydigitallife.info/2006/11/08/oracle-ora-14074-create-or-add-new-partition-fails-error/[/url]
[url]http://msutic.blogspot.com/2010/01/ora-14074-when-adding-partition-at.html[/url]