Hors contexte, cet article n’a pas beaucoup de sens ! Pourquoi utiliser la valeur NULL
dans une clé de partitionnement ? Evidemment, il ne s’agit pas d’encourager qui que ce soit à ce genre de pratiques ; ou au moins, il ne s’agit pas de l’encourager, plus que ça.
Oracle n’interdit pas d’utiliser NULL
dans une clé de partitionnement. Et comme ça n’est pas interdit, attendez-vous à ce que ce soit utilisé. En fait, il y a au moins 2 bonnes raisons à cette utilisation auxquelles je peux penser :
- Une erreur
- L’utilisation de clés multi-colonnes comme clé de partitionnement ; j’en reparlerai bientôt
Cet article illustre comment gérer une table partitionnée avec des clés de partitionnement NULL
.
Contexte
Commençons par un petit rappel sur l’utilisation du partitioning. Soit une table partitionnée par RANGE
:
create table T1(mydate date,
othercols number)
partition by range(mydate)
(partition data2010
values less than (to_date('01/01/2011','DD/MM/YYYY')));
Vous ne pouvez pas insérer de données dont la partition correspondante n’existe pas. Voici un exemple :
insert into t1
values (to_date('01/01/2011','DD/MM/YYYY'), 1);
*
ERROR at line 1:
ORA-14400: inserted partition key does not map to any partition
Pour éviter ce problème, vous effectuerez des opérations de maintenance régulière (et sans doute automatiques) pour créer les partitions par anticipation :
alter table T1
add partition data2011
values less than (to_date('01/01/2012','DD/MM/YYYY'));
insert into t1
values (to_date('01/01/2011','DD/MM/YYYY'), 1);
Ainsi naquit le partitionnement par Intervalle
Reprenons au début ; si vous ne voulez pas effectuer de maintenance (même automatique), créez simplement un partitionnement par Intervalle. Les partitions seront créées automatiquement :
drop table T1 purge;
create table T1(mydate date,
othercols number)
partition by range(mydate) interval(numtoyminterval(1,'YEAR'))
(partition data2010 values less than (to_date('01/01/2011','DD/MM/YYYY')));
insert into t1
values (to_date('01/01/2011','DD/MM/YYYY'), 1);
commit;
Et NULL
alors ?
Seulement voilà, dans le cas d’un partitionnement par Intervalle, si vous tentez d’insérer NULL
, la punition est presque la même que dans le cas d’une valeur inexistante ; remarquez la petite nuance :
insert into t1
values (null, 2);
*
ERROR at line 1:
ORA-14300: partitioning key maps to a partition outside maximum permitted
number of partitions
Et pourtant, on peut mettre NULL
Mais revenons à nos partitions gérées à la main :
drop table T1 purge;
create table T1(mydate date,
othercols number)
partition by range(mydate)
(partition data2010
values less than (to_date('01/01/2011','DD/MM/YYYY')));
Pour illustrer que, dans le monde d’avant, MAXVALUE
permet de créer des partitions qui stockent les NULL
:
alter table T1 add partition dataothers values less than (MAXVALUE);
insert into T1 values (null, 2);
commit;
select count(*) from T1 partition(dataothers);
COUNT(*)
--------
1
Dans ce cas, pour ajouter des partitions, il faudra passer par la commande SPLIT PARTITION
plutôt qu’un ADD PARTITION
:
alter table T1 split partition dataothers
at (to_date('01/01/2012','DD/MM/YYYY'))
into (partition data2011, partition dataothers)
update global indexes;
Partitioning List et Hash
Vous vérifierez avec les partitioning List et Hash, vous pouvez également stocker les valeurs NULL
:
drop table T1 purge;
create table T1(mydate date,
othercols number)
partition by hash(mydate) partitions 2;
insert into T1 values (null,1);
commit;
drop table T1 purge;
create table T1(mydate date,
othercols number)
partition by list(mydate)
(partition p1 VALUES (null));
insert into T1 values (null,1);
commit;
drop table T1 purge;
Une preuve de plus que, même quand on pense avoir pensé à tout, il en manque…
1 réflexion sur “Range Partitioning et Null”
This post was very useful for me to solve a problem. Thanks a lot!!
Rubem Costa
Brazil
Les commentaires sont fermés.