2010-02-17 31 views
1

我在我的postgres數據庫中有一些表,並且它們中的一些相互繼承。Postgres的串行值遞增2

例如:

CREATE TABLE parent_table(parent_table_id SERIAL PRIMARY KEY, 
     my_col1 VARCHAR(16) NOT NULL, 
     my_timestamp TIMESTAMP WITH TIME ZONE NOT NULL); 
CREATE TABLE child_table() INHERITS (parent_table); 
CREATE TABLE step_child_table() INHERITS (parent_table); 

我有一個觸發器,可以讓我在parent_table執行插入,然後計算出的數據是否真的不應該進入的兒童或者step_child表。

例如:

CREATE OR REPLACE FUNCTION my_parent_trigger() RETURNS TRIGGER AS $$ 
BEGIN 
    IF (NEW.my_col1 > 100) THEN 
     INSERT INTO child_table(my_col1, my_timestamp) VALUES (NEW.my_col1, NEW.my_timestamp); 
    ELSE 
     INSERT INTO step_child_table(my_col1, my_timestamp) VALUES (NEW.my_col1, NEW.my_timestamp); 
    END IF; 
    RETURN NULL; 
END; 
$$ 
CREATE TRIGGER my_trigger BEFORE INSERT ON parent_table FOR EACH ROW EXECUTE PROCEDURE my_parent_trigger(); 

的問題是,我的指標由2遞增。如果我插入一些數據,我做parent_table一個選擇,我看到我的索引從2開始,去到4,6,8,10,...如果我在child_table上進行選擇,我會看到我的索引(比如2,8和10),剩下的將放在另一個表中。

這是爲什麼?有沒有辦法阻止它?觸發器在插入前設置,所以我不明白爲什麼串行會增加兩次。

重要嗎?

在此先感謝。

回答

1

當你插入子表時,你需要包含parent_table_id列,我想。

現在,對於父插入,序列會前進一次,並將其中的值傳遞給NEW中的函數。然後將其扔掉,並在系統插入到子表中時要求系統生成一個新的。

因此,儘量在列列表中包含parent_table_id,並在其中插入NEW.parent_table_id的值。

+0

似乎解決了我的問題。我的插入現在看起來像「INSERT INTO child_table(parent_table_id,my_col1,my_timestamp)VALUES(NEW.my_parent_id,NEW.my_col1,NEW.my_timestamp);它解決了我的問題,但這是一個合法的舉動?鎖或任何通過操縱這樣的序列值,我是嗎? – cornercuttin 2010-02-18 13:45:53

+0

這是可以的,因爲子表使用與父表相同的順序 – Tometzky 2010-02-18 14:33:34

+0

不,這絕對是合法的舉動,如果有的話,它比你更「合法」原本是這樣,因爲默認情況下對孩子開槍可以導致做..呃。有趣的事情。如果沒有做對:-) – 2010-02-18 15:08:33

2

即使您得到此代碼只將序列遞增1,通常也不能指望從一個序列初始化的列中沒有間隔:begin; insert into foo (...); abort將使任何序列增加,即使事務已中止。

A. Elein Mustain顯示how to create a gapless sequence