3

I have some tables in my postgres database, and a few of them inherit from each other.

For example:

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);

I have a trigger that will let me perform an insert on parent_table, and then figure out whether or not the data should really go into child or step_child table.

for example:

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();

The problem is that my indexes are incrementing by 2. If I insert some data, and I do a select on parent_table, I see that my indexes start at 2, and go to 4, 6, 8, 10,... If I do a select on the child_table, I will see my indexes (say 2, 8, and 10), and the rest will be in the other table.

Why is this? Is there a way I can stop it? The trigger is set up BEFORE the insert, so I dont see why the serial would get incremented twice.

Does it matter?

Thanks in advance.

4

2 回答 2

2

我认为,当您插入子表时,您需要包含 parent_table_id 列。

现在,对于父插入,序列向前推进一次,然后将其中的值传递给 NEW 中的函数。然后你把它扔掉,并在你插入子表时要求系统生成一个新的。

所以尝试只在列列表中包含 parent_table_id,并在其中插入 NEW.parent_table_id 的值。

于 2010-02-18T09:32:13.397 回答
2

即使您让此代码仅将序列递增一,您通常也不能指望从序列初始化的列中没有间隙:begin; insert into foo (...); abort即使事务被中止,也会使任何序列递增。

A. Elein Musttain 展示了如何创建无间隙序列

于 2010-02-17T22:50:20.973 回答