让我说我有一张桌子:
- Column | Type | Notes
- ---------+------------ +----------------------------------------------------------
- id | integer | An ID that's FK to some other table
- seq | integer | Each ID gets it's own seq number
- data | text | Just some text,totally irrelevant.
id seq是组合键。
我想看到的是:
- ID | SEQ | DATA
- ----+------ +----------------------------------------------
- 1 | 1 | Quick brown fox,lorem ipsum,lazy dog,etc etc.
- 1 | 2 | Quick brown fox,etc etc.
- 1 | 3 | Quick brown fox,etc etc.
- 1 | 4 | Quick brown fox,etc etc.
- 2 | 1 | Quick brown fox,etc etc.
- 3 | 1 | Quick brown fox,etc etc.
- 3 | 2 | Quick brown fox,etc etc.
- 3 | 3 | Quick brown fox,etc etc.
- 3 | 4 | Quick brown fox,etc etc.
如你所见,id和seq的组合是唯一的。
我不知道如何设置我的表(或插入语句?)来做到这一点。我想插入id和数据,导致seq是依赖于id的子序列。
没问题!我们要做两个表,东西和东西。东西将是您在问题中描述的表,事情是它所指的:
- CREATE TABLE things (
- id serial primary key,name text
- );
- CREATE TABLE stuff (
- id integer references things,seq integer NOT NULL,notes text,primary key (id,seq)
- );
然后,我们将使用一个触发器来设置,每次创建一个行时都会创建一个新的序列:
- CREATE FUNCTION make_thing_seq() RETURNS trigger
- LANGUAGE plpgsql
- AS $$
- begin
- execute format('create sequence thing_seq_%s',NEW.id);
- return NEW;
- end
- $$;
- CREATE TRIGGER make_thing_seq AFTER INSERT ON things FOR EACH ROW EXECUTE PROCEDURE make_thing_seq();
现在我们最终会得到thing_seq_1,thing_seq_2等等
现在,另外一个触发器的东西,以便它每次使用正确的顺序:
- CREATE FUNCTION fill_in_stuff_seq() RETURNS trigger
- LANGUAGE plpgsql
- AS $$
- begin
- NEW.seq := nextval('thing_seq_' || NEW.id);
- RETURN NEW;
- end
- $$;
- CREATE TRIGGER fill_in_stuff_seq BEFORE INSERT ON stuff FOR EACH ROW EXECUTE PROCEDURE fill_in_stuff_seq();
这将确保当行进入填充时,id列用于查找正确的序列来调用nextval。
这是一个示范:
- test=# insert into things (name) values ('Joe');
- INSERT 0 1
- test=# insert into things (name) values ('Bob');
- INSERT 0 1
- test=# select * from things;
- id | name
- ----+------
- 1 | Joe
- 2 | Bob
- (2 rows)
- test=# \d
- List of relations
- Schema | Name | Type | Owner
- --------+---------------+----------+----------
- public | stuff | table | jkominek
- public | thing_seq_1 | sequence | jkominek
- public | thing_seq_2 | sequence | jkominek
- public | things | table | jkominek
- public | things_id_seq | sequence | jkominek
- (5 rows)
- test=# insert into stuff (id,notes) values (1,'Keychain');
- INSERT 0 1
- test=# insert into stuff (id,'Pet goat');
- INSERT 0 1
- test=# insert into stuff (id,notes) values (2,'Family photo');
- INSERT 0 1
- test=# insert into stuff (id,'Redundant lawnmower');
- INSERT 0 1
- test=# select * from stuff;
- id | seq | notes
- ----+-----+---------------------
- 1 | 1 | Keychain
- 1 | 2 | Pet goat
- 2 | 1 | Family photo
- 1 | 3 | Redundant lawnmower
- (4 rows)
- test=#