Thread: multi-table unique index
-- Suppose I have several types of foos create table foo_types ( foo_type_id serial primary key, foo_name text not null ); -- And the foos itself: create table foo ( foo_id serial primary key, foo_type_id int not null references foo_types, foo_general_data1 text ); -- 1st special foo: create table foo_1 ( foo_1_id serial primary key, foo_id int not null references foo, foo_1_data1 int, foo_1_data2text ); -- 2nd special foo: create table foo_2 ( foo_2_id serial primary key, foo_id int not null references foo, foo_2_data1 numeric(8,2), foo_2_data2timestamp ); -- And I have bars that each have zero or more (special) foos. create table bar ( bar_id serial primary key ); create table bar_foos ( bar_id int not null references bar, foo_id int not null references foo ); -- Now how do I prevent that I can insert a foo_1 and a foo_2 with -- the same foo_id? Or is the design errorneous itself? -- Markus Bertheau Berlin, Berlin, Germany
Instead of using the "serial" datatype, you can set it to "int4 PRIMARY KEY DEFAULT nextval(foo_type_id_seq)" and you can manually create the sequence "foo_type_id_seq". This way all the tables share the same sequence. On Monday 23 June 2003 06:58 am, Markus Bertheau wrote: > -- Suppose I have several types of foos > > create table foo_types ( > foo_type_id serial primary key, > foo_name text not null > ); > > -- And the foos itself: > > create table foo ( > foo_id serial primary key, > foo_type_id int not null references foo_types, > foo_general_data1 text > ); > > -- 1st special foo: > > create table foo_1 ( > foo_1_id serial primary key, > foo_id int not null references foo, > foo_1_data1 int, > foo_1_data2 text > ); > > -- 2nd special foo: > > create table foo_2 ( > foo_2_id serial primary key, > foo_id int not null references foo, > foo_2_data1 numeric(8,2), > foo_2_data2 timestamp > ); > > -- And I have bars that each have zero or more (special) foos. > > create table bar ( > bar_id serial primary key > ); > > create table bar_foos ( > bar_id int not null references bar, > foo_id int not null references foo > ); > > -- Now how do I prevent that I can insert a foo_1 and a foo_2 with > -- the same foo_id? Or is the design errorneous itself? > > -- > Markus Bertheau > Berlin, Berlin, Germany > > ---------------------------(end of broadcast)--------------------------- > TIP 2: you can get off all lists at once with the unregister command > (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) -- Michael A Nachbaur <mike@nachbaur.com>
В Пнд, 23.06.2003, в 19:32, Michael A Nachbaur пишет: > Instead of using the "serial" datatype, you can set it to "int4 PRIMARY KEY > DEFAULT nextval(foo_type_id_seq)" and you can manually create the sequence > "foo_type_id_seq". > > This way all the tables share the same sequence. Yeah, but I want to force this behaviour. so that it cannot happen by accident when you insert records without relying on the sequence. -- Markus Bertheau. Berlin, Berlin. Germany.
On Monday 23 June 2003 11:16 am, Markus Bertheau wrote: > В Пнд, 23.06.2003, в 19:32, Michael A Nachbaur пишет: > > Instead of using the "serial" datatype, you can set it to "int4 PRIMARY > > KEY DEFAULT nextval(foo_type_id_seq)" and you can manually create the > > sequence "foo_type_id_seq". > > > > This way all the tables share the same sequence. > > Yeah, but I want to force this behaviour. so that it cannot happen by > accident when you insert records without relying on the sequence. I believe that's what I recommended. IIRC the "serial" datatype is simply a shortcut to what I listed above. This way, if you do not explicitly specify an id for your record, it'll pull the default; which retrieves a new values from the sequence. If you want to ensure that a value is unique when a record is inserted, even if the user explicitly specifies an ID values, you can create a unique trigger on the tables, but this depends on what you want to do.
В Пнд, 23.06.2003, в 20:34, Michael A Nachbaur пишет: > On Monday 23 June 2003 11:16 am, Markus Bertheau wrote: > > В Пнд, 23.06.2003, в 19:32, Michael A Nachbaur пишет: > > > Instead of using the "serial" datatype, you can set it to "int4 PRIMARY > > > KEY DEFAULT nextval(foo_type_id_seq)" and you can manually create the > > > sequence "foo_type_id_seq". > > > > > > This way all the tables share the same sequence. > > > > Yeah, but I want to force this behaviour. so that it cannot happen by > > accident when you insert records without relying on the sequence. > If you want to ensure that a value is unique when a record is inserted, even > if the user explicitly specifies an ID values, you can create a unique > trigger on the tables, but this depends on what you want to do. I believe what you described is what I want to do. What's a unique trigger, though? -- Markus Bertheau. Berlin, Berlin. Germany.
On Monday 23 Jun 2003 2:58 pm, Markus Bertheau wrote: > -- Suppose I have several types of foos > > create table foo_types ( > foo_type_id serial primary key, > foo_name text not null > ); > > -- And the foos itself: > > create table foo ( > foo_id serial primary key, > foo_type_id int not null references foo_types, > foo_general_data1 text > ); > > -- 1st special foo: > > create table foo_1 ( > foo_1_id serial primary key, > foo_id int not null references foo, > foo_1_data1 int, > foo_1_data2 text > ); An alternative to Markus' ideas in the other thread - store the type in foo/foo_1, then have a foreign key over both. The irritating thing is that you're duplicating the type info unnecessarily. CREATE TABLE foo (foo_id serial unique,foo_type_id int not null references foo_types,...PRIMARY KEY (foo_id,foo_type_id) ); CREATE TABLE foo_1 (extra_foo int4 not null,extra_type int4 not nullextra1 text,PRIMARY KEY (extra_foo, extra_type)CONSTRAINTlink_to_foo FOREIGN KEY (extra_foo,extra_type) REFERENCES foo_core (foo_id, foo_type_id) ); -- Richard Huxton