2014-02-14 44 views
1

我們在應用程序中使用基於繼承的分區。分區位於列上,以便每個分區對此列有不同的值。像這樣:子分區表中的常量列

CREATE TABLE base(
    tblock INT NOT NULL, 
    -- other fields -- 
); 

-- Create a partition 
CREATE TABLE partition_1(
    CHECK(tblock=1), 
    INHERITS base 
); 

有很多這樣的分區,每個分區都有大量的記錄(以百萬計)。整體數據庫大小在兆兆字節。

在上述模式中,即使每個分區在所有行中都具有該列的常量值,分區也必須具有列tblock。這顯然是對磁盤空間的浪費。

是否有任何方法來聲明分區,以便它實際上不會在磁盤上存儲tblock的值?

我們目前在Postgresql 9.2.6上。

+0

除非還有一些*其他*鍵也可以唯一標識哪些分區會發生什麼。你如何知道哪一行獲取哪個tblock? –

+0

@CraigRinger tblock確定每個行進入哪個分區,並在WHERE子句中用於約束排除。這意味着時間塊。沒有其他的關鍵。數據結構比當然顯示的要複雜一些。 – harmic

+0

好的,所以應用程序有一些方法可以知道某行感興趣的「tblock」是什麼?如果是這樣,請考慮讓應用程序直接查詢分區,而不是依賴於約束排除;這樣你不再需要'tblock'字段。 –

回答

0
當然,你可以寫觸發器,它會跳過某些列,但如果你這樣做,你會從分區 (constraint exclusions)

失去的好處,如果表是繼承

在這裏你不能放棄這一列

的一些例子

create table base(i integer, j integer); 
CREATE TABLE 
create table inh_1() inherits (base); 
CREATE TABLE 
create table inh_2() inherits (base); 
CREATE TABLE 

CREATE OR REPLACE FUNCTION part_trigger() 
RETURNS TRIGGER AS $$ 
BEGIN 
if NEW.j = 1 THEN INSERT INTO inh_1 (i) VALUES (NEW.i); 
    ELSIF NEW.j = 2 THEN INSERT INTO inh_2 (i) VALUES (NEW.i); 
    END IF; 
    RETURN NULL; 
END; 
$$ 
LANGUAGE plpgsql; 
CREATE FUNCTION 

CREATE TRIGGER insert_base 
    BEFORE INSERT ON base 
    FOR EACH ROW EXECUTE PROCEDURE part_trigger(); 
CREATE TRIGGER 


insert into base values (100,1); 
INSERT 0 0 
insert into base values (140,2); 
INSERT 0 0 
sebpa=# select * from base; 
    i | j 
-----+--- 
100 | 
140 | 
(2 rows) 

sebpa=# select * from inh_1; 
    i | j 
-----+--- 
100 | 
(1 row) 

sebpa=# select * from inh_2; 
    i | j 
-----+--- 
140 | 
(1 row) 
+0

感謝您的回答,但我們需要約束排除。 – harmic

+0

有沒有其他的辦法:(記住,如果你想使用約束排除,你必須使用「檢查」'分區'欄 – sebpa