Bu yazımda Partition’lar hakkın da bildiklerimi sizin ile paylaşmaya çalışacağım. Öncelik ile ön bilgi olması açısından Partition’lar ile ilgili olan Oracle View’leri size aktarayım. Bunlar DBA, ALL, & USERS olmak üzere 3 farklı aşamada olabilirler.
DBA | USER | ALL |
dba_tab_cols | user_tab_cols | all_tab_cols |
dba_ind_partitions | user_ind_partitions | all_ind_partitions |
dba_ind_subpartitions | user_ind_subpartitions | all_ind_subpartitions |
dba_lob_partitions | user_lob_partitions | all_lob_partitions |
dba_lob_subpartitions | user_lob_subpartitions | all_lob_subpartitions |
dba_subpartition_templates | user_subpartition_templates | all_subpartition_templates |
dba_subpart_col_statistics | user_subpart_col_statistics | all_subpart_col_statistics |
dba_subpart_histograms | user_subpart_histograms | all_subpart_histograms |
dba_subpart_key_columns | user_subpart_key_columns | all_subpart_key_columns |
dba_tab_partitions | user_tab_partitions | all_tab_partitions |
dba_tab_subpartitions | user_tab_subpartitions | all_tab_subpartitions |
Partitionlar ile ilgili Dictionary Object’lerin nerede olacağını gösterdikten sonra partition türlerini belirleyelim.
· Range partition (belirli bir limit aralığı)
· Hash partition (Hash fonksiyonunun ürettiği sonuca göre)
· List partition (belirli bir liste yapılarak o lste bazlı partition)
· Range-hash partition (partition range subpartition hash )
· Range-list partition (partition range subpartition list)
Partitionların Tableapaceler üzerindeki dağılıma bakacak olursak. Oracle bu konuda bize çok büyük esneklikler sağlıyor. İstediğimiz Partition’u istediğimiz Tablespace’ye taşımamıza yada istediğimiz yerde yaratmamıza izin veriyor. Aslında böylede olması gerekiyor çünkü partition ve subpartition yapısını kullanmak zorunda isek bunun sebebi tablolarımızın çok büyük boyutlu olması. Tabloyu tek bir tablespace’ye hapsetmek bu durumda mantıklı değil zaten. Tablespace’de yer kalmadığı zaman partition yada tabloları başka tablespace’lere taşıyarak geçici olarak da olsa yer sorununa bir çözüm getirebiliriz.
Partition’lu tablo yaratırken örnek tabloları ALL_OBJECTS ile dolduracağım. Nede olsa herkesin database’sinde mevcut. :))
RANGE PARTITION
create table range_part
(OWNER VARCHAR2(30 BYTE) NOT NULL,
OBJECT_NAME VARCHAR2(30 BYTE) NOT NULL,
SUBOBJECT_NAME VARCHAR2(30 BYTE),
OBJECT_ID NUMBER NOT NULL,
DATA_OBJECT_ID NUMBER,
OBJECT_TYPE VARCHAR2(19 BYTE),
CREATED DATE NOT NULL,
LAST_DDL_TIME DATE NOT NULL,
TIMESTAMP VARCHAR2(19 BYTE),
STATUS VARCHAR2(7 BYTE),
TEMPORARY VARCHAR2(1 BYTE),
GENERATED VARCHAR2(1 BYTE),
SECONDARY VARCHAR2(1 BYTE)
)
partition by range (object_id)
(partition part_01 values less than (20000) tablespace users,
partition part_02 values less than (40000) tablespace example,
partition part_03 values less than (60000) tablespace users,
partition part_04 values less than (maxvalue) tablespace users)
Burada partition yaratırken hata almamak için bu yöntemi kullanıyorum. Böylece gelen her kayıt mutlaka bir partition ile eşleşecektir.
Tablomu aşağıda sorgu ile dolduruyorum.
insert into range_part select * from all_objects
Bakalım partitionlarda kaçar kayıt var. Ayrıca aşağıdaki sorgu örneğinde partition bazlı tablo erişimine örnek var.
select count(*) from range_part partition (part_01) --15432
select count(*) from range_part partition (part_02) --19977
select count(*) from range_part partition (part_03) --8356
select count(*) from range_part partition (part_04) --0
Tablodaki toplam kayıta bakarsak partitionların toplamını bize verecektir.
select count(*) from range_part –43765
HASH PARTITION
create table hash_part
(OWNER VARCHAR2(30 BYTE) NOT NULL,
OBJECT_NAME VARCHAR2(30 BYTE) NOT NULL,
SUBOBJECT_NAME VARCHAR2(30 BYTE),
OBJECT_ID NUMBER NOT NULL,
DATA_OBJECT_ID NUMBER,
OBJECT_TYPE VARCHAR2(19 BYTE),
CREATED DATE NOT NULL,
LAST_DDL_TIME DATE NOT NULL,
TIMESTAMP VARCHAR2(19 BYTE),
STATUS VARCHAR2(7 BYTE),
TEMPORARY VARCHAR2(1 BYTE),
GENERATED VARCHAR2(1 BYTE),
SECONDARY VARCHAR2(1 BYTE)
)
partition by hash (object_id)
partitions 4
store in (users,users,example,users);
yaratmış olduğumuz bu partitionların isimlerini öğrenmek için
select * from user_tab_partitions
sorgusunun sonucuna bakmak gerekir. Bu sorgu sonucunda user’a ait partition’ların hepsini bulabiliriz. Hatta hangi tabloya ait olduklarını ve hangi tablespace’de yer aldıklarını görebiliriz.
Sorgumuzu biraz güzelleştirelim
select * from user_tab_partitions where lower(table_name)='hash_part'
LIST PARTITION
create table list_part
(OWNER VARCHAR2(30 BYTE) NOT NULL,
OBJECT_NAME VARCHAR2(30 BYTE) NOT NULL,
SUBOBJECT_NAME VARCHAR2(30 BYTE),
OBJECT_ID NUMBER NOT NULL,
DATA_OBJECT_ID NUMBER,
OBJECT_TYPE VARCHAR2(19 BYTE),
CREATED DATE NOT NULL,
LAST_DDL_TIME DATE NOT NULL,
TIMESTAMP VARCHAR2(19 BYTE),
STATUS VARCHAR2(7 BYTE),
TEMPORARY VARCHAR2(1 BYTE),
GENERATED VARCHAR2(1 BYTE),
SECONDARY VARCHAR2(1 BYTE)
)
partition by list (object_type)
(partition list_01 values ('CONSUMER GROUP','TABLE SUBPARTITION','SEQUENCE','SCHEDULE','JAVA DATA','TABLE PARTITION'),
partition list_02 values ('PROCEDURE','OPERATOR','WINDOW','PACKAGE','PACKAGE BODY','LIBRARY'),
partition list_03 values ('PROGRAM','TYPE BODY','JAVA RESOURCE','XML SCHEMA','TRIGGER','JOB CLASS'),
partition list_04 values ('TABLE','SYNONYM','VIEW','FUNCTION','WINDOW GROUP','INDEXTYPE'),
partition list_05 values ('INDEX','TYPE','EVALUATION CONTEXT','JAVA CLASS'));
insert into list_part select * from all_objects
select distinct object_type from all_objects
Listede olması gerekenleri ekledim ama oracle bir şeye kızdı neden acaba??
ORA-14400: inserted partition key does not map to any partition
ORA-14400: eklenen bölüm anahtarI hiçbir bölümle eşleşmiyor
Aslinda bu hatayı almaması gerekir bütün olasılıkları tek tek denedim oluyor ama tabloyu bir seferde almadı.
Düzeltme : aynı işlemi scriptte herhangibi bir değişiklik yapmadan denedim çalıştı. Benim TOAD kafayı yedi herhalde.
insert into list_part select * from all_objects where object_type='CONSUMER
GROUP'
Madem * ile yemiyorsun bende tek tek veririm sana buda çalışmasın göreyim seni :))
insert into list_part select * from all_objects
where object_type in ('CONSUMER GROUP','TABLE SUBPARTITION','SEQUENCE','SCHEDULE','JAVA DATA','TABLE PARTITION','PROCEDURE','OPERATOR','WINDOW','PACKAGE','PACKAGE BODY','LIBRARY','PROGRAM','TYPE BODY','JAVA RESOURCE','XML SCHEMA','TRIGGER','JOB CLASS','TABLE','SYNONYM','VIEW','FUNCTION','WINDOW GROUP','INDEXTYPE','INDEX','TYPE','EVALUATION CONTEXT','JAVA CLASS')
RANGE HASH PARTITION
Bu yapıda ise partitionlarımız range subpartitionlarımız ise hash şeklinde olacaktır.
create table range_hash_part
(OWNER VARCHAR2(30 BYTE) NOT NULL,
OBJECT_NAME VARCHAR2(30 BYTE) NOT NULL,
SUBOBJECT_NAME VARCHAR2(30 BYTE),
OBJECT_ID NUMBER NOT NULL,
DATA_OBJECT_ID NUMBER,
OBJECT_TYPE VARCHAR2(19 BYTE),
CREATED DATE NOT NULL,
LAST_DDL_TIME DATE NOT NULL,
TIMESTAMP VARCHAR2(19 BYTE),
STATUS VARCHAR2(7 BYTE),
TEMPORARY VARCHAR2(1 BYTE),
GENERATED VARCHAR2(1 BYTE),
SECONDARY VARCHAR2(1 BYTE)
)
partition by range (object_id)
subpartition by hash (object_name)
--tek tek her partition için yazmaktan ise aşağıdaki gibi bir template oluşturarak
--hepsinde yaratılmasını sağlarız
subpartition template(
subpartition sp1 tablespace users,
subpartition sp2 tablespace users,
subpartition sp3 tablespace users,
subpartition sp4 tablespace example)
(partition part_001 values less than (20000),
partition part_002 values less than (40000),
partition part_003 values less than (60000),
partition part_004 values less than (maxvalue));
insert into range_hash_part select * from all_objects
--Oluşturduğumuz subpartition’ları aşağıdaki sorgu ile görebiliriz.
select * from user_tab_SUBpartitions where table_name='RANGE_HASH_PART'
RANGE LIST PARTITION
Buradaki yapıda da partition’ları range şeklinde oluşturuyorum. Subpartition’lar ise list şeklinde.
create table range_list_part
(OWNER VARCHAR2(30 BYTE) NOT NULL,
OBJECT_NAME VARCHAR2(30 BYTE) NOT NULL,
SUBOBJECT_NAME VARCHAR2(30 BYTE),
OBJECT_ID NUMBER NOT NULL,
DATA_OBJECT_ID NUMBER,
OBJECT_TYPE VARCHAR2(19 BYTE),
CREATED DATE NOT NULL,
LAST_DDL_TIME DATE NOT NULL,
TIMESTAMP VARCHAR2(19 BYTE),
STATUS VARCHAR2(7 BYTE),
TEMPORARY VARCHAR2(1 BYTE),
GENERATED VARCHAR2(1 BYTE),
SECONDARY VARCHAR2(1 BYTE)
)
partition by range (object_id)
subpartition by list (object_type)
(partition part_01 values less than (20000)
(
subpartition sub01_part_01 values ('TABLE','VIEW','INDEX'),
subpartition sub01_part_02 values ('SEQUENCE','PROCEDURE','PACKAGE')
),
partition part_02 values less than (40000)
(
subpartition sub02_part_01 values ('TABLE','VIEW','INDEX'),
subpartition sub02_part_02 values ('SEQUENCE','PROCEDURE','PACKAGE')
),
partition part_03 values less than (maxvalue)
(
subpartition sub03_part_01 values ('TABLE','VIEW','INDEX'),
subpartition sub03_part_02 values ('SEQUENCE','PROCEDURE','PACKAGE')
)
);
Bu tablo’yu doldurmak için aşağıdaki sorguyu kullanabiliriz. Gönül isterdi bütün object_type’ları almak ama yazma işi biraz ameliliğe döneceği için işin kolayına kaçtım :)).
insert into range_list_part select * from all_objects
where object_type in ('SEQUENCE','PROCEDURE','PACKAGE','TABLE','VIEW','INDEX')
No comments:
Post a Comment