PostgreSQL 10 partition Declerative Partition


   Merhabalar, PostgreSQL 10 'da Partition yapısı her versiyonunda değişiklik gösterdiği gibi diğer platformlar Oracle, MsSql gibi VeriTabanlarından da oldukça farklılık gösterir.
   Postgres 9.x versiyonlarında Tablonun partitionu bir trigger yardımı ile yapılmakta ve fiziksel olarak child tablolar yaratılmakta.
   Postgres 10 versiyonu ile önceki versiyonlarda Tabloları partition ve child tabloları adreslemek için kullanılan bu trigger yapısından kurtulmuş oluyoruz. (Kurtuluş tabi nereden baktığınıza bağlı :) )
   Declerative Partition yapısı ile yine fiziksel child tabloları manuel yaratıp Indexlerini de Local olarak bu fiziksel tablolara yaratıyoruz.
   Aşağıda bir örnekleme yaptım. Bu örnekte bir Log Tablosu ve günlere göre Range Partition yapısı mevcut.

CREATE TABLE Table_Log (
    id INTEGER NOT NULL,
    operation_date  timestamp without time zone NOT NULL,
    response_time integer
)PARTITION BY RANGE (operation_date)
TABLESPACE pg_default;

Child tabloları oluşturuyoruz.. Oracle ve MSSQL den tamamen farklı bir mantık.

CREATE TABLE Table_Log_20180131 PARTITION OF Table_Log FOR VALUES FROM ('31-JAN-18') TO ('01-FEB-18');
CREATE TABLE Table_Log_20180201 PARTITION OF Table_Log FOR VALUES FROM ('01-FEB-18') TO ('02-FEB-18');
CREATE TABLE Table_Log_20180202 PARTITION OF Table_Log FOR VALUES FROM ('02-FEB-18') TO ('03-FEB-18');
CREATE TABLE Table_Log_20180203 PARTITION OF Table_Log FOR VALUES FROM ('03-FEB-18') TO ('04-FEB-18');

Şimdi bu tablolara birer index tanımı yapalım.

CREATE TABLE Table_Log_20180131 PARTITION OF Table_Log FOR VALUES FROM ('31-JAN-18') TO ('01-FEB-18');

CREATE TABLE Table_Log_20180201 PARTITION OF Table_Log FOR VALUES FROM ('01-FEB-18') TO ('02-FEB-18');
CREATE TABLE Table_Log_20180202 PARTITION OF Table_Log FOR VALUES FROM ('02-FEB-18') TO ('03-FEB-18');
CREATE TABLE Table_Log_20180203 PARTITION OF Table_Log FOR VALUES FROM ('03-FEB-18') TO ('04-FEB-18');

Evet Range partition tablomuz basic olarak hazır. Bunun yanında List partitionda kullanabilirsiniz. Pk kullanmak isterseniz bunu child tabloları yaratırken oluşturmanız gerekiyor.

CREATE TABLE Table_Log_20180131 PARTITION OF Table_Log (operation_date, PRIMARY KEY (id)) FOR VALUES FROM ('31-JAN-18') TO ('01-FEB-18');

Aynı şekilde konstraint gerekiyorsa bunu child tablo üzerinden yapabilir siniz.

ALTER TABLE table_log_20180202 ADD CONSTRAINT check_date CHECK (operation_date >= '02-FEB-18' AND operation_date < '03-FEB-18');

Yine partition kısmını dettach-attach edebiliriz.

ALTER TABLE Table_Log DETACH PARTITION Table_Log_20180131;

ALTER TABLE Table_Log ATTACH PARTITION Table_Log_20180131 FOR VALUES FROM ('31-JAN-18') TO ('01-FEB-18');

Özetlemek gerekiyorsa bahsettiğimiz gibi Partition tabloları & Indexleri manuel yaratmamız gerekiyor. Yeni bir partition eklemek için ayrı bir rutin yazmanız yada takviminize eklemeniz gerekiyor.
Ana tablo üzerinde Primary Key ve Unique Key MASTER Tablo üzerinden olmuyor bunu child tablolardan yapmanız gerekli.
Partition tabloları şu şekilde listeyebilir siniz.

SELECT
    nmsp_parent.nspname AS parent_schema,
    parent.relname      AS parent,
    nmsp_child.nspname  AS child_schema,
    child.relname       AS child
FROM pg_inherits
    JOIN pg_class parent         ON pg_inherits.inhparent = parent.oid
    JOIN pg_class child          ON pg_inherits.inhrelid   = child.oid
    JOIN pg_namespace nmsp_parent ON nmsp_parent.oid  = parent.relnamespace
    JOIN pg_namespace nmsp_child    ON nmsp_child.oid   = child.relnamespace
WHERE parent.relname='table_log';

parent_schema | parent | child_schema | child
---------------+-----------+--------------+--------------------
public | table_log | public | table_log_20180131
public | table_log | public | table_log_20180201
public | table_log | public | table_log_20180202
public | table_log | public | table_log_20180203
(4 rows)

postgres=#

Hiç yorum yok:

Ara